$ scope。$在$ rootScope时不能正常工作。$ broadcast确实如此

时间:2014-07-22 15:44:52

标签: angularjs angularjs-scope angular-ui-router angularjs-controller

这是我的父母控制器,我在那里听取事件

app.controller("SectionLayoutController", function($scope) {

  $scope.$on("sectionLayout.doAction", function(e, options) {
    // do some stuff
  });

});

在我的孩子控制器中,我这样做

$scope.$emit("sectionLayout.doAction", { someOption: "something" });

事件应该在父控制器中触发,但它不是。在发出事件之前,我确实检查了我的子控制器范围的内容(使用console.log),并且该事件的监听器确实存在于其父事件之一中。

enter image description here

也许是因为子控制器的范围不是正在监听事件的范围的直接子节点?这不是一个真正的关键问题,因为我可以用

替换该行
$rootScope.$broadcast("sectionLayout.doAction", { someOption: "something" });

并且它工作正常,但我仍然很好奇为什么$ scope。$ emit不工作(它确实在某个时候工作,它只是随机停止)。

(Angular版本1.2.16)

1 个答案:

答案 0 :(得分:1)

修改

问题似乎是angular.js中的一个错误,而不是ui-router(它已经被报告并计划在版本1.3 https://github.com/angular/angular.js/issues/5489中修复)。在指令中使用ng-transclude似乎为指令创建了一个兄弟范围,这使得这种层次结构(使用我的第一个plunker示例):http://i.imgur.com/4OUxJSP.png

所以是的,我想现在我将使用$ rootScope。$ broadcast


好的,从我发现的情况来看,这是ui-router的错误(忘了提到我正在使用它,哎呀)。

如果子路径的ui-view位于transcluded指令内,事件将卡在那里。这是该行动中http://plnkr.co/edit/zgqAPiDbB2LUtwJaeHhN?p=preview的一个漏洞。 Dummy控制器使用sectionLayout指令并且ui-view被转换(正如您在dummy.html中看到的那样)。

<!-- dummy.html -->
<div section-layout="layout">
  <!-- transcluded stuff -->
  <div ui-view></div>
</div>

<!-- sectionlayout.html -->
<div>
  <p>Section Layout for {{layout.title}}</p>
  <p ng-repeat="r in recieves">{{r.message}}</p>

  <div ng-transclude style="background-color: #EEE;"></div>
</div>

这是$ scope。$ emit确实起作用的另一个plunkr,唯一的区别是ui-view直接在sectionlayout.html内,而不是在指令http://plnkr.co/edit/mVftwkZrynkF6KanE4zV?p=preview中被转换。

<!-- dummy.html -->
<div section-layout="layout"></div>

<!-- sectionlayout.html -->
<div>
  <p>Section Layout for {{layout.title}}</p>
  <p ng-repeat="r in recieves">{{r.message}}</p>

  <div ui-view style="background-color: #EEE;"></div>
</div>

这是一个完全不同的plunkr,我不使用ui-router,但它仍然是一样的。在父级中使用指令,其中侦听事件,并且子控制器在指令中被转换。在这一个中,$ scope。$ emit和$ rootScope。$ broadcast工作正常,所以它似乎是ui-router中转换的ui-views的错误。 http://plnkr.co/edit/Iz5YcbMiTzrXQ6bJMskK?p=preview

<div ng-controller="ParentController">
  <p>Parent Controller</p>
  <p ng-repeat="r in recieves">{{r.message}}</p>

  <div my-directive>
    <div ng-controller="ChildController" style="background-color: #EEE;">
      <p>Child Controller</p>
      <button ng-click="tryEmit()">$scope.$emit</button>
      <button ng-click="tryBroadcast()">$rootScope.$broadcast</button>
    </div>
  </div>
</div>

我会在他们的github页面上报告这个错误