Angular中控制器之间的通信

时间:2014-11-05 07:36:46

标签: angularjs angularjs-controller

我熟悉以下方法来实现控制器之间的通信。

还有其他人吗?是否有更好的方法/最佳实践?


$broadcast / $emit

.controller("Parent", function($scope){
  $scope.$broadcast("SomethingHappened", {..});
  $scope.$on("SomethingElseHappened", function(e, d){..});
})
.controller("Child", functions($scope){
  $scope.$broadcast("SomethingElseHappened", {..});
  $scope.$on("SomethingHappened", function(e, d){..});
})
.controller("AnotherChild", functions($scope){
  $scope.$on("SomethingHappened", function(e, d){..});
});

或者,从视图:

<button ng-click="$broadcast('SomethingHappened', data)">Do Something</button>

优点:

  • 适合一次性活动

缺点:

  • 在兄弟姐妹之间不起作用,除非使用共同的祖先,如$rootScope


函数的范围继承

<div ng-controller="Parent">
  <div ng-controller="Child">
    <div ng-controller="ChildOfChild">
       <button ng-click="someParentFunctionInScope()">Do</button>
    </div>
  </div>
</div>

或代码

.controller("ChildOfChild", function($scope){
   $scope.someParentFunctionInScope();
});

优点:

  • 适合从上到下的数据传播

缺点:

  • 从底部到顶部不太好,因为它需要一个对象(而不是原始对象)
  • 调用祖先函数会产生紧耦合
  • 在兄弟姐妹之间不起作用,除非使用共同的祖先,如$rootScope


范围继承+ $watch

控制器仅对范围暴露数据的变化做出反应,从不调用函数。

.controller("Parent", function($scope){
  $scope.VM = {a: "a", b: "b"};
  $scope.$watch("VM.a", function(newVal, oldVal){
    // react
  });
}

优点:

  • 适用于不是由控制器创建的子范围,例如:比如ng-repeat

缺点:

  • 根本不适用于一次性活动
  • 代码不太可读

其他值得注意的提及:

  • 具有专门功能的共享服务
  • 更一般的Pub / Sub服务
  • $rootScope

3 个答案:

答案 0 :(得分:6)

正如Samuel所述,使用服务共享数据是一种推荐的方法。这个想法是无论任何控制器如何,数据的状态都是一致的。 这两篇文章可以让您了解“如何”和“为什么”:Sharing Data Between ControllersThe state of angularjs controllers

答案 1 :(得分:5)

我使用特定于功能的共享服务来在控制器之间进行通信。

您可以创建一个通用共享服务,使其具有订阅和广播事件的中心点,但我发现特定于功能的服务随着时间的推移更容易维护,尤其是在项目和团队增长时。

答案 2 :(得分:0)

- 继承还有另一种选择,可以在控制器之间共享数据:

var app = angular.module('myApp', []);

    var parent = function($scope){
        $scope.parent = {
             parentData: 'some data'
        }
    };

    // you could do some prototyping as well
//parent.prototype.parent2 = {
//    parentData: 'some more data'
//};

    var child = function($scope){
        parent.call(this, $scope);
        //$scope.parent2 = this.parent2; here is how you access that data.
    };
    child.prototype = Object.create(parent.prototype);
    child.prototype.constructor = child;


app.controller('parent', parent);

app.controller('myController', child);

这种方法给你一个优势:

  • 不需要使用兄弟姐妹范围和DOM结构。

您可以继续使用创建自定义属性的对象,然后冻结&#39;数据变量用于保存相同的数据并确保数据不被修改等。

最后,我更喜欢使用服务在控制器之间共享数据,并使用观察者模式或pub / sub与rootscope emit / on来确认控制器内的操作。