赞
踩
本文翻译自:Working with $scope.$emit and $scope.$on
How can I send my $scope
object from one controller to another using .$emit
and .$on
methods? 如何使用.$emit
和.$on
方法将$scope
对象从一个控制器发送到另一个控制器?
- function firstCtrl($scope) {
- $scope.$emit('someEvent', [1,2,3]);
- }
-
- function secondCtrl($scope) {
- $scope.$on('someEvent', function(mass) { console.log(mass); });
- }
It doesn't work the way I think it should. 它不像我认为的那样工作。 How do $emit
and $on
work? $emit
和$on
work如何运作?
参考:https://stackoom.com/question/yqdK/使用-scope-emit和-scope-on
First of all, parent-child scope relation does matter. 首先,父子范围关系确实很重要。 You have two possibilities to emit some event: 你有两种可能发出一些事件:
$broadcast
-- dispatches the event downwards to all child scopes, $broadcast
- 将事件向下发送到所有子范围, $emit
-- dispatches the event upwards through the scope hierarchy. $emit
- 通过范围层次结构向上调度事件。 I don't know anything about your controllers (scopes) relation, but there are several options: 我对控制器(范围)关系一无所知,但有几种选择:
If scope of firstCtrl
is parent of the secondCtrl
scope, your code should work by replacing $emit
by $broadcast
in firstCtrl
: 如果范围firstCtrl
是母公司secondCtrl
范围,你的代码应该通过更换工作$emit
由$broadcast
在firstCtrl
:
function firstCtrl($scope) { $scope.$broadcast('someEvent', [1,2,3]); } function secondCtrl($scope) { $scope.$on('someEvent', function(event, mass) { console.log(mass); }); }
In case there is no parent-child relation between your scopes you can inject $rootScope
into the controller and broadcast the event to all child scopes (ie also secondCtrl
). 如果您的范围之间没有父子关系,您可以将$rootScope
注入控制器并将事件广播到所有子范围(即secondCtrl
)。
function firstCtrl($rootScope) { $rootScope.$broadcast('someEvent', [1,2,3]); }
Finally, when you need to dispatch the event from child controller to scopes upwards you can use $scope.$emit
. 最后,当您需要将子控制器中的事件调度到范围向上时,您可以使用$scope.$emit
。 If scope of firstCtrl
is parent of the secondCtrl
scope: 如果firstCtrl
范围是firstCtrl
范围的父secondCtrl
:
function firstCtrl($scope) { $scope.$on('someEvent', function(event, data) { console.log(data); }); } function secondCtrl($scope) { $scope.$emit('someEvent', [1,2,3]); }
You can call a service from your controller that returns a promise and then use it in your controller. 您可以从控制器调用返回承诺的服务,然后在控制器中使用它。 And further use $emit
or $broadcast
to inform other controllers about it. 并进一步使用$emit
或$broadcast
来通知其他控制器。 In my case, I had to make http calls through my service, so I did something like this : 在我的情况下,我不得不通过我的服务进行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
- })
- }
and my service looks like this 我的服务看起来像这样
- 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);
- });
-
- }
-
- }])
I would additionally suggest a 4th option as a better alternative to the proposed options by @zbynour. 我还建议第四个选项作为@zbynour提议选项的更好替代方案。
Use $rootScope.$emit
rather than $rootScope.$broadcast
regardless of the relationship between trasmitting and receiving controller. 无论传输和接收控制器之间的关系如何,都使用$rootScope.$emit
而不是$rootScope.$broadcast
。 That way, the event remains within the set of $rootScope.$$listeners
whereas with $rootScope.$broadcast
the event propagates to all children scopes, most of which will probably not be listeners of that event anyway. 这样,事件保持在$rootScope.$$listeners
的集合中,而使用$rootScope.$broadcast
,事件传播到所有子范围,其中大多数可能不是该事件的监听器。 And of course in the receiving controller's end you just use $rootScope.$on
. 当然,在接收控制器的最后,你只需使用$rootScope.$on
。
For this option you must remember to destroy the controller's rootScope listeners: 对于此选项,您必须记住销毁控制器的rootScope侦听器:
- var unbindEventHandler = $rootScope.$on('myEvent', myHandler);
- $scope.$on('$destroy', function () {
- unbindEventHandler();
- });
This is my function: 这是我的功能:
- $rootScope.$emit('setTitle', newVal.full_name);
-
- $rootScope.$on('setTitle', function(event, title) {
- if (scope.item)
- scope.item.name = title;
- else
- scope.item = {name: title};
- });
- <!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>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。