TL; DR跳到底部 - >
我在Codepen上发现了一个ng-class示例,here(下面重现了重要代码)。
在其中,作者创建了一个简单的菜单栏,突出显示活动项目。很标准。然而,我认为他这样做的方式很有趣,所以我把它修改为对我更有意义的东西,并且令人惊讶的是它破了。
作者创造了他的观点:
...
<div>Change the active menu item:
<input ng-model="states.activeItem" />
</div>
<ul class="navigation">
<li ng-repeat="item in items" class="item" ng-class="{'active': item.id == states.activeItem}" ng-click="states.activeItem=item.id">{{item.title}}</li>
</ul>
....
虽然他的控制器看起来像
app.controller('NavigationController', function ($scope) {
// Must use a wrapper object, otherwise "activeItem" won't work
$scope.states = {};
$scope.states.activeItem = 'item1';
$scope.items = [{
id: 'item1',
title: 'Home'
}, {
id: 'item2',
title: 'Public Rooms'
}, {
id: 'item3',
title: 'My Rooms'
}];
});
对我来说,我认为跳过states
变量并且只有一个
$scope.activeItem
所以我将控制器更改为,并将视图更改为
<div>Change the active menu item:
<input ng-model="states.activeItem" />
</div>
<ul class="navigation">
<li ng-repeat="item in items" class="item" ng-class="{'active': item.id == activeItem}" ng-click="activeItem=item.id">{{item.title}}</li>
</ul>
但它现在不起作用。
因此,出于某种原因,Angular需要将这些变量存储在新对象中。但为什么呢?
TL; DR:这两个都是Codepens:
The Original(效果很好)
Mine(不起作用)
为什么不开采工作?
答案 0 :(得分:2)
这是因为ng-repeat
指令在每次迭代中创建一个新范围。如 ng-repeat
documentation :
ngRepeat 指令从a中为每个项目实例化一次模板 采集。每个模板实例都有自己的范围,给定的范围 loop变量设置为当前集合项,并设置$ index 到项目索引或键。
使用对象通过范围继承为子范围提供对其父范围的访问。使用本机或基元,将选择当前子作用域仅访问父作用域一次,然后一旦为其分配了特定值,它将创建该本机/原始作用域变量。您可以将ng-click="activeItem=item.id"
表达式作为先前陈述的证明。要解决此问题:您有两个选项,创建一个将状态保存到活动范围继承查找的对象,或使用$parent
属性访问父范围ng-click="$parent.activeItem=item.id"
,这也适用于{ {1}}指令,ng-class
<强> HTML 强>
ng-class="{'active': item.id == $parent.activeItem}"