使用 AngularJS 服务从其他模块更新其他控制器中的范围

Using AngularJS service to update scope in other controller from other module

我是 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() 函数时,它会看到 mainCtrl 也使用的服务中的 currentID 参数。

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

$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>

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

我同意 uksz,你应该使用 broadcast/emit 让其他范围知道更改,让他们根据需要处理。

广播到元素的所有子范围

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

发射到该元素的所有父级范围

$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);
    }
  };
});

最后,您可以在作用域上包含一个函数,这样您就可以让父作用域知道发生了什么

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