编辑>这是我正在尝试做的更好的事情: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-start
和 ng-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/