【问题标题】:Unable to broadcast event from parent controller in angularjs无法从 angularjs 中的父控制器广播事件
【发布时间】:2015-08-20 07:16:35
【问题描述】:

我有两个具有父子关系的控制器:

这是父控制器的路由:

angular.module('app')
  .config(function ($stateProvider) {
    $stateProvider
      .state('data-show', {
        url: '/data',
        templateUrl: 'app/data.html',
        controller: 'DataCtrl'
      });
  });

这是父控制器的 HTML:

<div class="block-header">
   ...
   ...
    <div ng-include="'components/child_page.html'"></div>
</div>

父控制器代码:

angular.module('app')
  .controller('DataCtrl', function ($scope) {

      $rootScope.$broadcast('someEvent', [1,2,3]);
 });

子控制器是child_page.html页面的一部分,如上所示,使用ng-include标签包含在父页面中。

这是子控制器的外观:

angular.module('app')
    .controller('childCtrl', function ($scope) {

        $scope.$on('someEvent', function(event, mass) {
            console.log('EVENT CALLED');
        });
  });

子页面的 HTML:

<div ng-controller="childCtrl">
    <div id="myGrid"></div>
</div>

但即使我从父控制器广播事件,该事件也不会在子页面中被调用。

【问题讨论】:

  • 我敢打赌,原因是在广播事件时子控制器尚未加载 - 所以没有人可以听。在控制器函数中添加一些console.log 将验证这一点。
  • @NikosParaskevopoulos:在我广播事件之前,我正在写信给控制台broadcasting & 在子控制器的第一行,我正在写信给控制台child controller is loaded。如果我现在检查控制台,我首先会看到 broadcasting 消息,然后是 child controller is loaded 。我这里有什么?

标签: angularjs angularjs-scope angularjs-routing angularjs-controller


【解决方案1】:

我正在回答我自己的问题,希望对某人有所帮助。

正如Nikos Paraskevopoulos 所建议的,当我尝试从父控制器广播事件时,子控制器未加载。

所以我把父控制器改成:

angular.module('app')
  .controller('DataCtrl', function ($scope,$timeout) {

      $timeout(function () {
        $scope.$broadcast('someEvent', [1, 2, 3]);
      }, 300);

 });

我添加了 300 毫秒的延迟,以允许加载子控制器。

【讨论】:

  • $timeout 这样做真的很危险——最好远离它!主要原因:如果由于某种原因,模板在 400 毫秒内加载怎么办 => 错误。
  • @NikosParaskevopoulos:你说的有道理,但我尝试通过 rootscope 传播事件,但没有成功:(
  • 好吧,它可能需要一些调整; $includeContentLoaded 事件带有创建的范围;您也许可以使用 that 范围进行广播。
【解决方案2】:

来自cmets:

我敢打赌,原因是广播事件时子控制器尚未加载 - 所以没有人可以听。

而且似乎得到了验证:

在广播事件之前,我正在写信给控制台“广播”,并且在子控制器的第一行,我正在写信给“控制台子控制器已加载”。如果我现在检查控制台,我首先会看到“广播”消息,然后是“加载子控制器”。

查看ng-include 的文档,它会在加载内容时发出$includeContentLoaded 事件。所以第一种方法是:

// parent controller:
$rootScope.$on('$includeContentLoaded', function() {
    $rootScope.$broadcast('someEvent', [1,2,3]);
});

稍后可以使用事件的参数对其进行优化。

【讨论】:

  • 感谢您的快速帮助。我尝试使用 rootScope 但它没有帮助,相反我现在使用 $timeout 在广播事件之前添加 300 毫秒的延迟。谢谢你指引我正确的方向。这个问题浪费了我将近一半的时间:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-11
  • 1970-01-01
  • 2013-09-30
  • 2016-03-01
  • 2015-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多