angularjs - 本地修改后, Angular 嵌套范围不响应广播

标签 angularjs angularjs-scope

编辑>这是我正在尝试做的更好的事情:http://plnkr.co/edit/E5WU0IJ5eZOJmr393AFU?p=preview

保留为遗产 -> 这是旧的 Plunker http://plnkr.co/edit/7q2qJq8LEPtNwcl8RZqE?p=preview

我有 2 个按钮,它们通过向其子级发送 $broadcast 来打开/关闭。

子 Controller 监听$on打开/关闭点击并相应地修改 bool open

但是,如果我在本地范围内修改 open bool 值,$on 监听器似乎会分离并且不再触发。

我建议查看 plunker,但这是来源:

脚本.js:

angular.module('testApp', [])
  .controller('BaseCtrl', ['$scope',
    function($scope) {
      $scope.items = ['foo', 'bar', 'tar', 'far', 'car'];
    }
  ])
  .controller('ItemCtrl', ['$scope',
    function($scope) {
      $scope.open = true;

      $scope.$on('Open_True', function() {
        $scope.open = true;
      });
      $scope.$on('Open_False', function() {
        $scope.open = false;
      });

    }
  ]);

和 html:

<!DOCTYPE html>
<html ng-app="testApp">

<head>
  <script data-require="angular.js@*" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
  <script src="script.js"></script>
</head>

<body ng-controller="BaseCtrl">

  <button ng-click="$broadcast('Open_True')">Open All</button>
  <button ng-click="$broadcast('Open_False')">Close All</button>

  <br><br>

  <div ng-controller="ItemCtrl">
    <div ng-repeat-start="item in items">
      Item: {{item}}
      <br>We are open: {{open}}
      <!-- This is the button that breaks it all -->
      <button ng-click="open=!open">Toggle Open</button>
    </div>
    <div ng-repeat-end style="padding-left: 1em">
      Item: {{item}}
      <br>We are open: {{open}}
      <hr style="margin-left:-1em;">
    </div>
  </div>
</body>

</html>

我认为问题出在我的 ItemCtrl 所在的位置,但不太确定。我最大的问题是我需要执行 ng-repeat-start 因为我有两个兄弟元素需要重复,所以我无法将 Controller 放在第一个 div 中 block 。

感谢您的任何想法。

最佳答案

您遇到的问题是,当您使用ng-repeat时,会创建一个子作用域。当您更改其中一个子级的 open 时,它会使用自己的本地作用域 open 变量,并且不再遵循父级作用域的 open 版本。

您可以使用 $parent.open 从子作用域内显式更改或访问父作用域的 open 版本。

这是更新的 PLUNK它显示了每个项目的父作用域和本地作用域中 open 变量的状态,以便您可以了解广播到父作用域时实际发生的情况。

--编辑--

您可以通过为子元素添加 Controller 来解决此问题。然后在 Controller 中,您可以监听广播并进行相应更新:

在您的标记中:

<div ng-repeat="item in items" ng-controller="ChildCtrl">

在您的脚本中:

.controller('ChildCtrl', ['$scope', function($scope) {
  $scope.$on('Open_True', function(){
    $scope.open = true;
  });
  $scope.$on('Open_False', function(){
    $scope.open = false;
  });
}])

已更新PLUNK这表明子作用域现在尊重广播。

--编辑--

如果您只想重复同级元素,则可以只用两个嵌套同级元素重复一个 div,而不是使用 ng-repeat-startng-repeat-end :

<div ng-repeat="item in items" ng-controller="ItemCtrl">
  Item: {{item}}
  <button ng-click="open=!open" >Toggle Open</button>
  <!-- SIBLINGS -->
  <div>Sibling one is open: {{open}}</div>
  <div style="margin-left: 1em;">Sibling two is open: {{open}}</div>
  <hr />
</div>

另一个更新PLUNK

--编辑--

既然您提到所需的输出是一个表格,其中重复一行..可以用同样的方式完成:

<table>
  <tr ng-repeat="item in items" ng-controller="ItemCtrl">
    <td><button ng-click="open=!open">toggle</button></td>
    <!-- SIBLINGS -->
    <td>Sibling 1 is open: {{open}}</td>
    <td>Sibling 2 is open: {{open}}</td>
  </tr>
</table>

希望最终更新PLUNK .

关于angularjs - 本地修改后, Angular 嵌套范围不响应广播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23299891/

相关文章:

javascript - 在导航栏中滚动(Bootstrap 3),但保持页面的其余部分不变

javascript - Angularjs - 在导航中 ng-repeat 在渲染期间显示更多行

javascript - 我的范围变量不会在 html View 中更新

javascript - 了解范围、ng-click 和 Angular 方式

javascript - AngularJS - 将 this.value 传递给函数

angularjs - ng-repeat 在 ng-transclude(指令)中

javascript - 使用 angular.js 访问和修改在模板中启动的模型

angularjs - 使用 expressjs 时下载的 .pdf 文件已损坏

javascript - 如何在 Angular.Js 中封装 $scope

javascript - AngularJS:动态绑定(bind) Click in 指令被触发多次