使用 $scope.$emit 和 $scope.$on

2022-08-29 22:15:29

如何使用 和 方法将对象从一个控制器发送到另一个控制器?$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


答案 1

首先,父子范围关系确实很重要。您有两种可能发出某些事件:

  • $broadcast-- 将事件向下调度到所有子作用域,
  • $emit-- 通过作用域层次结构向上调度事件。

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

  1. 如果 scope 是作用域的父级,则代码应通过在 中替换为 来工作:firstCtrlsecondCtrl$emit$broadcastfirstCtrl

    function firstCtrl($scope)
    {
        $scope.$broadcast('someEvent', [1,2,3]);
    }
    
    function secondCtrl($scope)
    {
        $scope.$on('someEvent', function(event, mass) { console.log(mass); });
    }
    
  2. 如果作用域之间没有父子关系,则可以注入控制器并将事件广播到所有子作用域(即也)。$rootScopesecondCtrl

    function firstCtrl($rootScope)
    {
        $rootScope.$broadcast('someEvent', [1,2,3]);
    }
    
  3. 最后,当您需要将事件从子控制器向上调度到作用域时,可以使用 。如果 作用域 是作用域的父级:$scope.$emitfirstCtrlsecondCtrl

    function firstCtrl($scope)
    {
        $scope.$on('someEvent', function(event, data) { console.log(data); });
    }
    
    function secondCtrl($scope)
    {
        $scope.$emit('someEvent', [1,2,3]);
    }
    

答案 2

我还要建议使用第4个选项作为@zbynour所提议选项的更好替代方案。

使用而不是不管传输和接收控制器之间的关系。这样,事件将保留在集合内,而事件将传播到所有子作用域,其中大多数子作用域可能无论如何都不会是该事件的侦听器。当然,在接收控制器的末端,您只需使用。$rootScope.$emit$rootScope.$broadcast$rootScope.$$listeners$rootScope.$broadcast$rootScope.$on

对于此选项,您必须记住销毁控制器的 rootScope 侦听器:

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