如何将我的$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如何工作?


当前回答

首先,亲子范围关系确实很重要。你有两种可能触发事件:

$broadcast——向下分派事件到所有子作用域, $emit——通过作用域层次结构向上分派事件。

我对你的控制器(作用域)关系一无所知,但有几个选项:

If scope of firstCtrl is parent of the secondCtrl scope, your code should work by replacing $emit by $broadcast in 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 (i.e. also 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. If scope of firstCtrl is parent of the secondCtrl scope: function firstCtrl($scope) { $scope.$on('someEvent', function(event, data) { console.log(data); }); } function secondCtrl($scope) { $scope.$emit('someEvent', [1,2,3]); }

其他回答

作用域可用于将事件传播、分派到作用域的子对象或父对象。

$emit -将事件传播到父节点。$broadcast -向儿童传播事件。 监听事件的方法,由$emit和$broadcast传播。

index . html示例:

<div ng-app="appExample" ng-controller="EventCtrl">
      Root(Parent) scope count: {{count}}
  <div>
      <button ng-click="$emit('MyEvent')">$emit('MyEvent')</button>
      <button ng-click="$broadcast('MyEvent')">$broadcast('MyEvent')</button><br>

      Childrent scope count: {{count}} 
  </div>
</div>

示例app.js:

angular.module('appExample', [])
.controller('EventCtrl', ['$scope', function($scope) {
  $scope.count = 0;
  $scope.$on('MyEvent', function() {
    $scope.count++;
  });
}]);

在这里你可以测试代码: http://jsfiddle.net/zp6v0rut/41/

首先,亲子范围关系确实很重要。你有两种可能触发事件:

$broadcast——向下分派事件到所有子作用域, $emit——通过作用域层次结构向上分派事件。

我对你的控制器(作用域)关系一无所知,但有几个选项:

If scope of firstCtrl is parent of the secondCtrl scope, your code should work by replacing $emit by $broadcast in 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 (i.e. also 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. If scope of firstCtrl is parent of the secondCtrl scope: function firstCtrl($scope) { $scope.$on('someEvent', function(event, data) { console.log(data); }); } function secondCtrl($scope) { $scope.$emit('someEvent', [1,2,3]); }

你可以从控制器调用一个返回承诺的服务,然后在控制器中使用它。并进一步使用$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);
                });

        }

    }])

根据angularjs事件文档,接收端应该包含这样结构的参数

@params

——{Object} event是包含事件信息的事件对象

——由被调用者传递的{Object}参数(注意,这只能是一个,所以总是在字典对象中发送更好)

美元的范围。$on('fooEvent',函数(事件,args) {console.log(args)}); 从你的代码

另外,如果你想让共享信息在不同的控制器间可用,还有另一种方法可以实现,那就是angular服务。由于服务是单例的,信息可以跨控制器存储和获取。只需在该服务中创建getter和setter函数,公开这些函数,在服务中创建全局变量并使用它们存储信息

为了将$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一样快。