AngularJs 中控制器之间的通信
Communicating between controllers in AngularJs
我有一个简单的问题:在(比方说)两个控制器之间进行交互时,最好的 ('cleanest'、'scaleable') 路径是什么。那会是定义一个服务并观察该服务的 return-value 以便做出反应吗?
我设置了一个简单示例 here,我在其中查看服务的当前值:
$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>
并将您的控制器更改为
app.controller('cntrl1', function(myService, $scope) {
$scope.myService = myService;
$scope.update = function(str) {
$scope.myService.setValue(str);
}
});
app.controller('cntrl2', function(myService, $scope) {
$scope.myService = myService;
$scope.update = function(str) {
$scope.myService.setValue(str);
}
});
使用$broadcast/$emit
正如@squiroid 指出的那样,您可以使用 $broadcast
将事件广播到任何正在监视目标事件的控制器。
请注意,您最好不要使用 $rootScope.$broadcast + $scope.$on
,而应使用 $rootScope.$emit+ $rootScope.$on
,因为 $broadcast
事件会在所有后代范围内冒泡,这可能会导致严重的性能问题。
这是最好的通信方式b/w控制器通过服务共享相同的数据,但它是有限的b/w具有相同服务的控制器:-
相反,您也可以选择广播由其他控制器捕获的事件并相应地更改该数据,这种方式更具可扩展性但不干净:-)
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
听 Ctrl :-
$rootScope.$on('update', function (event, data) {
console.log(data); // 'Some data'
});
我有一个简单的问题:在(比方说)两个控制器之间进行交互时,最好的 ('cleanest'、'scaleable') 路径是什么。那会是定义一个服务并观察该服务的 return-value 以便做出反应吗?
我设置了一个简单示例 here,我在其中查看服务的当前值:
$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>
并将您的控制器更改为
app.controller('cntrl1', function(myService, $scope) {
$scope.myService = myService;
$scope.update = function(str) {
$scope.myService.setValue(str);
}
});
app.controller('cntrl2', function(myService, $scope) {
$scope.myService = myService;
$scope.update = function(str) {
$scope.myService.setValue(str);
}
});
使用$broadcast/$emit
正如@squiroid 指出的那样,您可以使用 $broadcast
将事件广播到任何正在监视目标事件的控制器。
请注意,您最好不要使用 $rootScope.$broadcast + $scope.$on
,而应使用 $rootScope.$emit+ $rootScope.$on
,因为 $broadcast
事件会在所有后代范围内冒泡,这可能会导致严重的性能问题。
这是最好的通信方式b/w控制器通过服务共享相同的数据,但它是有限的b/w具有相同服务的控制器:-
相反,您也可以选择广播由其他控制器捕获的事件并相应地更改该数据,这种方式更具可扩展性但不干净:-)
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
听 Ctrl :-
$rootScope.$on('update', function (event, data) {
console.log(data); // 'Some data'
});