来自子控制器的$ emit工作,但来自父范围的$ broadcast不能

时间:2014-03-11 13:55:49

标签: javascript angularjs angularjs-scope

当我打电话给$scope.$broadcast时,我的孩子听到的所有事件都没有被触发。简化示例如下:

HTML

下面是我想要完成的一个简化示例:

<div ng-app="app" ng-controller="parentCtrl">
  <div ng-controller="childCtrl">
    <b>Parent Event:</b> {{outer}}<br />
    <b>Child Event:</b> {{inner}}<br />
  </div>
</div>

AngularJs

mc = angular.module('app', [
  'app.controllers',
]);

angular.module('app.controllers', [])
    .controller('parentCtrl', ['$scope', '$http', '$q', function ($scope, $http, $q) {
        $scope.outer = 'not executed';
        $scope.$broadcast('EventFromParent');
        $scope.$on('EventFromChild', function () { 
          $scope.outer = 'executed';
        });        
    }])
    .controller('childCtrl', ['$scope', '$http', function ($scope, $http) {
        $scope.inner = 'not executed';
        $scope.$on('EventFromParent', function () { 
          $scope.inner = 'executed';
        });
        $scope.$emit('EventFromChild');
    }]);

输出

我希望看到父母和孩子都被触发,但我没有被触发为Child。

EXPECTED                      ACTUAL
------                        ------
Parent Event: triggered       Parent Event: triggered
Child Event: triggered        Child Event: not triggered

理论

我的猜测是子控制器还没准备好接收事件。我需要等到DOM准备就绪,但我不知道如何使用Angular。请随意告诉我,这也是我正在做的事情的错误方法。

Plunkr

1 个答案:

答案 0 :(得分:11)

问题是父控制器中的$scope.$broadcast在子控制器中$scope.$on之前被调用,因此在事件发生时,没有听众可以使用此事件。广播到儿童范围。

您需要在广播或发布事件之前注册事件侦听器。在您的情况下,实现这一目标的一种方法是使用$timeout

$timeout(function() {
    $scope.$broadcast('EventFromParent');
});

(您需要首先注入$timeout服务)

这样,你已经有效地延迟了事件广播,并且事件监听器有机会自己注册,所以当事件发生时,将调用监听器。