AngularJs中控制器之间的通信
我有一个简单的问题:当涉及到两个控制器之间的交互时,最好的(“最干净的”,“可伸缩的”)路径是什么。这是定义一个服务并观察该服务的返回值以做出反应吗 我设置了一个简单的示例,其中我观察服务的当前值:AngularJs中控制器之间的通信,angularjs,angularjs-service,angularjs-controller,Angularjs,Angularjs Service,Angularjs Controller,我有一个简单的问题:当涉及到两个控制器之间的交互时,最好的(“最干净的”,“可伸缩的”)路径是什么。这是定义一个服务并观察该服务的返回值以做出反应吗 我设置了一个简单的示例,其中我观察服务的当前值: $scope.$watch( function() { return myService.getValue(); }, function(newVal) { $scope.value1 = newVal; }); 并在单击其中一个按钮
$scope.$watch(
function() {
return myService.getValue();
},
function(newVal) {
$scope.value1 = newVal;
});
并在单击其中一个按钮时更新该服务的值
这能做得更好,更小,更干净吗?这里的最佳实践是什么
干杯。使用服务在控制器之间共享数据
您的案例尝试在控制器之间共享数据,而不是在控制器中观察服务的价值,我认为直接将服务对象引用到控制器的范围是更好的方法
所以你的观点可以是
<pre ng-controller="cntrl1">Value in cntrl1: {{ myService.value }} <button ng-click="update('value1')">Change to 'value1'</button></pre>
<pre ng-controller="cntrl2">Value in cntrl2: {{ myService.value }} <button ng-click="update('value2')">Change to 'value2'</button></pre>
使用$broadcast/$emit
正如@squiroid所指出的,您可以使用$broadcast
向监控目标事件的任何控制器广播事件
请注意,您最好不要使用
$rootScope.$broadcast+$scope.$on
,而是使用$rootScope.$emit+$rootScope.$on
,因为$broadcast
事件将在所有子代作用域中冒泡,这可能会导致严重的性能问题。这是与通过服务共享相同数据的控制器进行通信的最佳方式,但与具有相同服务的控制器进行通信的方式有限:-
相反,您也可以选择广播由其他控制器捕获的事件,并相应地更改数据,这种方式更具可伸缩性,但不干净:-)
或
按Ctrl键收听:-
$rootScope.$on('update', function (event, data) {
console.log(data); // 'Some data'
});
这个解决方案更简单,但$broadcast事件将遍历所有子代作用域,对吗$emit可能会更好。是的,在性能方面,如果您只收听rootScope,emit将工作得更好。谢谢:-)D'oh-很简单,但也很好!谢谢你,伙计。$scope.update=function(){…}可以避免重复吗?关于封装根范围,这很有效,谢谢。订阅服务不是一种“更干净”的方法,而不是去根范围做这些事情吗?您可以直接使用
ng click=“myService.value='value1'”
,而不是使用$scope.update=function()
,这是一种直截了当的方法,可以避免冗余代码。就个人而言,我更喜欢订阅服务,而不是在rootscope上广播。Angular服务是单例的,可以作为引用传递,所以简单地将服务注入控制器是一种自然的JavaScript思维方式。
Sender ctrl :-
$rootScope.$broadcast('update', 'Some data'); //method that lets pretty much everything hear it even $scope too.
$rootScope.$emit('update', 'Some data');// only lets other $rootScope listeners catch it
$rootScope.$on('update', function (event, data) {
console.log(data); // 'Some data'
});