在 angular 中我们经常会使用多个 controller 和 指令
他们拥有各自的 $scope , 这就产生了跨$scope调用的问题。
有几种常见的方法来可以使用.
方法一 : 指令 require
<div directive1="xx"> <div directive2></div> </div> directive("directive1", [function () { return { restrict: "A", link: function () { }, scope: true, controller: ["$scope", function ($scope) { this.alert = function () { $scope.name = "100" } }], name: "directive1Controller" } }]). directive("directive2", [function () { return { restrict: "E", require: "^directive1Controller", //调用父级指令的controller link: function (scope, elem, attrs, directive1Controller) { directive1Controller.alert(); //使用方法 } } }]).
指令通过require,调用其它指令controller方法, 达到通讯
方法二 : service
service("sharing", [function () { this.data = ""; }]). controller("ctrl", ["$scope", "sharing", function ($scope, sharing) { $scope.updateData = function () { sharing.data = "new value"; } }]). directive("directive1", ["sharing", function (sharing) { return { restrict: "A", link: function (scope) { scope.$watch(function () { return sharing.data; }, function () { scope.name = sharing.data; }); } } }]).
模块间如果要通讯最好使用 service 来提供接口 , 那service 和 controller 间可以通过 $watch 来更新$scope.
$watch 有些缺点,内存消耗多
方法3 :事件
controller("ctrl", ["$scope", "sharing", "$rootScope", function ($scope, sharing, $rootScope) { $scope.updateData = function () { $rootScope.$broadcast("sharingChange", "new value"); //$emit 是向上冒泡广播 //$broadcast 是向下广播 } }]). directive("directive1", ["sharing", function (sharing) { return { restrict: "A", link: function (scope) { scope.$on("sharingChange", function (e, newValue) { scope.name = newValue; }); } } }]).
这是比较官方的做法。
总结 :
子层和父层通讯,多使用继承的$scope, 指令的 require ,事件广播
模块间的通讯使用service提供接口会比较容易看的明白, service 和 controller 指令间的通讯,可以用watch,$on或者全局变量(模块内的全局,别用太多既可)
service 接口虽然好, 不过由于指令复用性很高,如果每个操作都开接口的话,很快接口就会很多,所以要确保接口是复用性高的,如果只是为了某次开发为配合某模块而开就不值得了。
$rootScope.$broadcast("Main.myParent.alert", function ($scope) { //某个模块, (通过传入操作方法,这里直接写操作$scope) $scope.name = "keatkeat" }); $scope.$on("Main.myParent.alert", function (e, fn) { //常用指令 fn($scope); //调用操作方法并把$scope传入,让外部的逻辑实现操作$scope });
我们可以把复用性不高的操作,写在外面,这样就可以不用写太多的接口了。
新闻热点
疑难解答