当前位置:   article > 正文

使用$ scope。$ emit和$ scope。$ on_$scope.$emit

$scope.$emit

本文翻译自: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对象从一个控制器发送到另一个控制器?

  1. function firstCtrl($scope) {
  2. $scope.$emit('someEvent', [1,2,3]);
  3. }
  4. function secondCtrl($scope) {
  5. $scope.$on('someEvent', function(mass) { console.log(mass); });
  6. }

It doesn't work the way I think it should. 它不像我认为的那样工作。 How do $emit and $on work? $emit$on work如何运作?


#1楼

参考:https://stackoom.com/question/yqdK/使用-scope-emit和-scope-on


#2楼

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: 我对控制器(范围)关系一无所知,但有几种选择:

  1. If scope of firstCtrl is parent of the secondCtrl scope, your code should work by replacing $emit by $broadcast in firstCtrl : 如果范围firstCtrl是母公司secondCtrl范围,你的代码应该通过更换工作$emit$broadcastfirstCtrl

     function firstCtrl($scope) { $scope.$broadcast('someEvent', [1,2,3]); } function secondCtrl($scope) { $scope.$on('someEvent', function(event, mass) { console.log(mass); }); } 
  2. 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]); } 
  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]); } 

#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调用,所以我做了类似这样的事情:

  1. function ParentController($scope, testService) {
  2. testService.getList()
  3. .then(function(data) {
  4. $scope.list = testService.list;
  5. })
  6. .finally(function() {
  7. $scope.$emit('listFetched');
  8. })
  9. function ChildController($scope, testService) {
  10. $scope.$on('listFetched', function(event, data) {
  11. // use the data accordingly
  12. })
  13. }

and my service looks like this 我的服务看起来像这样

  1. app.service('testService', ['$http', function($http) {
  2. this.list = [];
  3. this.getList = function() {
  4. return $http.get(someUrl)
  5. .then(function(response) {
  6. if (typeof response.data === 'object') {
  7. list = response.data.results;
  8. return response.data;
  9. } else {
  10. // invalid response
  11. return $q.reject(response.data);
  12. }
  13. }, function(response) {
  14. // something went wrong
  15. return $q.reject(response.data);
  16. });
  17. }
  18. }])

#4楼

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侦听器:

  1. var unbindEventHandler = $rootScope.$on('myEvent', myHandler);
  2. $scope.$on('$destroy', function () {
  3. unbindEventHandler();
  4. });

#5楼

This is my function: 这是我的功能:

  1. $rootScope.$emit('setTitle', newVal.full_name);
  2. $rootScope.$on('setTitle', function(event, title) {
  3. if (scope.item)
  4. scope.item.name = title;
  5. else
  6. scope.item = {name: title};
  7. });

#6楼

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
  5. <script>
  6. var app = angular.module('MyApp',[]);
  7. app.controller('parentCtrl',function($scope){
  8. $scope.$on('MyEvent',function(event,data){
  9. $scope.myData = data;
  10. });
  11. });
  12. app.controller('childCtrl',function($scope){
  13. $scope.fireEvent = function(){
  14. $scope.$emit('MyEvent','Any Data');
  15. }
  16. });
  17. </script>
  18. </head>
  19. <body ng-app="MyApp">
  20. <div ng-controller="parentCtrl" ng-model="myName">
  21. {{myData}}
  22. <div ng-controller="childCtrl">
  23. <button ng-click="fireEvent()">Fire Event</button>
  24. </div>
  25. </div>
  26. </body>
  27. </html>
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/222804
推荐阅读
相关标签
  

闽ICP备14008679号