2015-11-02 98 views
1

更新其他控制器范围我是AngularJS一个新手,所以也许我在看这个错误的方式。如果是这样,请指向正确的方向。使用AngularJS服务从其他模块

基本上我想更新驻留在另一个模块中的另一控制器一些DOM元素。 我试图通过服务发送数据,但它似乎没有在目标范围上更新。

var mainModule = angular.module('main', []); 
var appModule = angular.module('app', ['main']); 


appModule.controller("appCtrl", function ($scope, $routeParams, mainService) { 

    $scope.mainService = mainService; 

    var initialize = function() { 
     $scope.mainService.currentID = $routeParams.productId; 
    } 

    initialize(); 
}); 


mainModule.factory('mainService', function() { 
    var mainService = { currentID: 0 }; 
    return mainService 
}); 

mainModule.controller('mainCtrl', ['$scope', 'mainService', function ($scope, mainService) { 

    $scope.mainService = mainService; 
    $scope.function1Url = "function1/" + $scope.mainService.currentID; 
    $scope.function2Url = "function2/" + $scope.mainService.currentID; 
    //CurrentID is always 0!! 
}]); 

我预计,在appCtrl调用initialize()功能时,它会看到currentID PARAM其中也使用mainCtrl服务。

+0

您忘了注入$ routeParams –

回答

2

对于使用服务更新控制器,我强烈建议你使用$rootScope.$broadcast$rootScope.$on。这里是链接的,你如何能做到这一点的例子,一个博客:

$rootScope.$broadcast('myCustomEvent', { 
    someProp: 'Sending you an Object!' // send whatever you want 
}); 

// listen for the event in the relevant $scope 
$rootScope.$on('myCustomEvent', function (event, data) { 
    console.log(data); // 'Data to send' 
}); 

http://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/

这是你的工作的解决方案:

var mainModule = angular.module('main', []); 
var productModule = angular.module('product', ['main']); 

productModule.service('mainService', ['$rootScope', '$timeout', function ($rootScope, $timeout) { 
    this.method1 = function() { 
     alert('broadcast'); 
      $rootScope.$broadcast('myCustomEvent', { 
       newValue: 'This is an updated value!' 
      }); 
    } 
}]); 

productModule.controller('mainCtrl', ['$scope', '$rootScope', function ($scope, $rootScope){ 

    $scope.myValue = 'Initial value'; 

    $rootScope.$on('myCustomEvent', function (event, data) { 
     $scope.myValue = data.newValue; 
     alert('received broadcast'); 
    }); 

}]); 

productModule.controller("productCtrl", function ($scope, mainService) { 

    $scope.mainService = mainService; 
    $scope.clickMe = 'Click to send broadcast'; 

    $scope.callService = function() { 
     $scope.clickMe = 'Broadcast send!'; 
     $scope.mainService.method1(); 
    } 


}); 

和HTML:

<body ng-app='main'> 
    <div ng-controller="mainCtrl"><b>My value:</b>{{myValue}}</div> 

    <div id="product" ng-controller="productCtrl"> 
     <button ng-click="callService()">{{clickMe}}</button> 
    </div> 

    <script type="text/javascript">angular.bootstrap(document.getElementById("product"), ['product']);</script> 
    </body> 
+0

请注意$ rootScope。$ broadcast将发送给所有范围(性能)。使用$ scope。$发出,如果你需要通知的是你。或$ scope。$如果它是你的孩子,则广播。 – Vince

+0

我试过$ rootScope。$广播,但它似乎从来没有收到。我已经成立了一名Plunker来展示这个问题。 [Plunker链接](http://plnkr.co/edit/GjTxszyE5iVDy1DN9V7H?p=preview) – Wesman80

+0

我得到它的工作 – uksz

0

你有几个不同的方法来做到这一点。

我uksz同意,你应该使用的广播/发射让其他示波器知道的变化,让他们去处理需要。

广播转到元素的所有子范围

$scope.$broadcast("Message Name", "payload, this can be an object"); 

的Emit进入这个元素

$scope.$emit("message name", "payload, this can be an object"); 

另一种选择是,你也可以要求其他控制器的所有父范围

appModule.directive('myPane', function() { 
    return { 
    require: '^myTabs', 
    scope: {}, 
    link: function(scope, element, attrs, tabsCtrl) { 
     tabsCtrl.addPane(scope); 
    } 
    }; 
}); 

最后,你可以包括范围的功能,所以你可以让家长SCO pe知道发生了什么

appModule.directive('myPane', function() { 
    return { 
    scope: { 
     doSomething: '&something' 
    }, 
    link: function(scope, element, attrs) { 
     $scope.doSomething(test); 
    } 
    }; 
});