如何将我的$scope对象从一个控制器发送到另一个使用。$emit和。$on方法?
function firstCtrl($scope) {
$scope.$emit('someEvent', [1,2,3]);
}
function secondCtrl($scope) {
$scope.$on('someEvent', function(mass) { console.log(mass); });
}
这不是我想的那样。$emit和$on如何工作?
如何将我的$scope对象从一个控制器发送到另一个使用。$emit和。$on方法?
function firstCtrl($scope) {
$scope.$emit('someEvent', [1,2,3]);
}
function secondCtrl($scope) {
$scope.$on('someEvent', function(mass) { console.log(mass); });
}
这不是我想的那样。$emit和$on如何工作?
当前回答
你必须使用$rootScope在同一个应用程序的控制器之间发送和捕获事件。下面是一个工作示例。
app.controller('firstCtrl', function($scope, $rootScope) {
function firstCtrl($scope) {
{
$rootScope.$emit('someEvent', [1,2,3]);
}
}
app.controller('secondCtrl', function($scope, $rootScope) {
function secondCtrl($scope)
{
$rootScope.$on('someEvent', function(event, data) { console.log(data); });
}
}
链接到$scope对象的事件只在所有者控制器中工作。控制器之间的通信是通过$rootScope或Services完成的。
其他回答
为了将$scope对象从一个控制器发送到另一个控制器,我将讨论$rootScope。$broadcast和$rootScope。$emit是最常用的。
案例1:
$rootScope.$broadcast:-
$rootScope.$broadcast('myEvent',$scope.data);//Here `myEvent` is event name
$rootScope.$on('myEvent', function(event, data) {} //listener on `myEvent` event
$rootScope监听器不会自动销毁。你需要使用$destroy来销毁它。最好使用$scope。$scope上的监听器$on被自动销毁,即一旦$scope被销毁。
$scope.$on('myEvent', function(event, data) {}
Or,
var customeEventListener = $rootScope.$on('myEvent', function(event, data) {
}
$scope.$on('$destroy', function() {
customeEventListener();
});
案例2:
rootScope。美元发出:
$rootScope.$emit('myEvent',$scope.data);
$rootScope.$on('myEvent', function(event, data) {}//$scope.$on not works
$emit和$broadcast的主要区别是$rootScope。$emit事件必须使用$rootScope监听。$on,因为触发的事件从来没有向下通过作用域树。 在这种情况下,您还必须像使用$broadcast一样销毁侦听器。
编辑:
我不喜欢使用$rootScope。$broadcast + $scope。$on但使用 rootScope美元。发出+ rootScope。美元美元。rootScope美元。美元广播+ 美元的范围。$on组合可能会导致严重的性能问题。这是 因为事件会在所有范围内扩散。
编辑2:
在这个回答中提到的问题已经在angular.js中解决了 1.2.7。编写版本$broadcast现在避免冒泡未注册的作用域 运行速度和$emit一样快。
<!DOCTYPE html>
<html>
<head>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
var app = angular.module('MyApp',[]);
app.controller('parentCtrl',function($scope){
$scope.$on('MyEvent',function(event,data){
$scope.myData = data;
});
});
app.controller('childCtrl',function($scope){
$scope.fireEvent = function(){
$scope.$emit('MyEvent','Any Data');
}
});
</script>
</head>
<body ng-app="MyApp">
<div ng-controller="parentCtrl" ng-model="myName">
{{myData}}
<div ng-controller="childCtrl">
<button ng-click="fireEvent()">Fire Event</button>
</div>
</div>
</body>
</html>
我还会建议第四个选项,作为@zbynour提议的选项的更好替代方案。
使用rootScope美元。$emit而不是$rootScope。不管发送和接收控制器之间的关系。这样,事件就保留在$rootScope的集合中。$$监听器,而$rootScope。将事件传播到所有子作用域,其中大多数子作用域可能不是该事件的监听器。当然,在接收控制器端,你只需使用$rootScope。$on。
对于这个选项,你必须记得销毁控制器的rootScope监听器:
var unbindEventHandler = $rootScope.$on('myEvent', myHandler);
$scope.$on('$destroy', function () {
unbindEventHandler();
});
根据angularjs事件文档,接收端应该包含这样结构的参数
@params
——{Object} event是包含事件信息的事件对象
——由被调用者传递的{Object}参数(注意,这只能是一个,所以总是在字典对象中发送更好)
美元的范围。$on('fooEvent',函数(事件,args) {console.log(args)}); 从你的代码
另外,如果你想让共享信息在不同的控制器间可用,还有另一种方法可以实现,那就是angular服务。由于服务是单例的,信息可以跨控制器存储和获取。只需在该服务中创建getter和setter函数,公开这些函数,在服务中创建全局变量并使用它们存储信息
你可以从控制器调用一个返回承诺的服务,然后在控制器中使用它。并进一步使用$emit或$broadcast通知其他控制器。 在我的情况下,我必须通过我的服务进行http调用,所以我做了这样的事情:
function ParentController($scope, testService) {
testService.getList()
.then(function(data) {
$scope.list = testService.list;
})
.finally(function() {
$scope.$emit('listFetched');
})
function ChildController($scope, testService) {
$scope.$on('listFetched', function(event, data) {
// use the data accordingly
})
}
我的服务是这样的
app.service('testService', ['$http', function($http) {
this.list = [];
this.getList = function() {
return $http.get(someUrl)
.then(function(response) {
if (typeof response.data === 'object') {
list = response.data.results;
return response.data;
} else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
}])