2014-11-23 29 views
0

TL; DR跳到底部 - >如果范围变量不在对象中,为什么不会ng类工作?

我发现Codepen,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

它有角的范围继承做。我建议你阅读这个有趣的帖子http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs – kubuntu 2014-11-23 11:40:12

回答

2

这是因为ng-repeat指令会在每次迭代中创建一个新的作用域。正如ng-repeat documentation说:

ngRepeat指令实例从 收集模板每个项目一次。每个模板实例都有自己的作用域,其中给定的 循环变量设置为当前的集合项目,并且$ index将 设置为项目索引或键。

使用对象使用范围继承为子范围提供对其父范围的访问。使用本地或原语,将选择当前的子范围只访问一次父范围,然后一旦它被赋予一个特定的值,它就会创建该本地/原始范围变量。你可以拿你的ng-click="activeItem=item.id"表达式作为前面陈述的佐证。为了改善这种情况:你有两个选择,创建一个对象,将保留您的状态活跃范围继承查询,或者使用$parent属性来访问父范围,ng-click="$parent.activeItem=item.id",这也适用于ng-class指令,ng-class="{'active': item.id == $parent.activeItem}"

DEMO

HTML

<h3>Using the `$parent` scope property</h3> 
<ul> 
    <li ng-repeat="item in items track by $index" 
    ng-class="{'active': $parent.activeItem == item.id}" 
    ng-click="$parent.activeItem = item.id" 
    ng-bind="item.name"></li> 
</ul> 

<h3>Using an object state</h3> 
<ul> 
    <li ng-repeat="item in items track by $index" 
    ng-class="{'active': state.activeItem == item.id}" 
    ng-click="state.activeItem = item.id" 
    ng-bind="item.name"></li> 
</ul> 
+0

真棒解释!谢谢 – CodyBugstein 2014-11-23 12:19:28

+0

您可以在[** AngularJS github wiki **](https://github.com/angular/angular.js/wiki)中阅读更多关于范围的信息,结帐[** Understanding Scopes **](https: //github.com/angular/angular.js/wiki/Understanding-Scopes)部分。不要忘了阅读[** Developer's Guide **](https://docs.angularjs.org/guide)以及干杯:) – ryeballar 2014-11-23 12:47:17

相关问题