我已经阅读所有的文档和Stack Overflow关于这个主题的答案,并了解问题。我相信我已经避开了所有常见的陷阱。
所以我理解我的代码失败,因为ng-repeat指令创建的范围。我自己的指令创建一个隔离范围,并且双向数据绑定到父范围中的一个对象。我的指令将分配一个新的对象值到这个绑定的变量,当我的指令使用没有ng-repeat(父变量正确更新)时,这工作完美。然而,使用ng-repeat,该赋值在ng-repeat范围中创建一个新变量,父变量不会看到该变化。所有这一切都是基于我已经阅读的预期。
我也读过,当一个给定的元素有多个指令时,只创建一个作用域。并且可以在每个指令中设置优先级以定义应用指令的顺序;指令按优先级排序,然后调用其编译函数(在http://docs.angularjs.org/guide/directive处搜索字优先级)。
所以我希望我可以使用优先级,以确保我的指令运行第一,并最终创建一个隔离范围,当ng-repeat运行时,它重新使用隔离范围,而不是创建范围,原型继承父范围。 ng-repeat文档声明该指令运行在优先级1000.不清楚1是较高优先级还是较低优先级。当我在我的指令中使用优先级1,它没有什么区别,所以我试过2000年。但是这使事情更糟:我的双向绑定变得未定义,我的指令不显示任何东西。
我创建了a fiddle to show my issue.我已经注释掉了我的指令中的优先级设置。我有一个名称对象的列表和一个名为name-row的指令,显示名称对象中的名字和姓氏字段。当单击显示的名称时,我希望它在主作用域中设置一个选定的变量。名称数组,所选变量使用双向数据绑定传递给名称 – 行伪指令。
我知道如何通过调用主作用域中的函数来使这个工作。我也知道,如果选择是在另一个对象,我绑定到外部对象,事情会工作。但我目前对这些解决方案不感兴趣。
相反,我有的问题是:
>如何防止ng-repeat创建一个范围,从原型继承父范围,而是使用我的指令的隔离范围?
>为什么优先级2000在我的指令不工作?
>使用Batarang,是否有可能知道使用什么类型的范围?
> ngRepeat不会影响您选择的隔离范围
>传递给ngRepeat以在指令的属性上使用的参数使用原型继承的作用域
>您的指令不起作用的原因与隔离范围无关
<li ng-repeat="name in names" ng-class="{ active: $index == selected }" ng-click="selected = $index"> {{$index}}: {{name.first}} {{name.last}} </li>
这里是一个JSFiddle,表明它不会工作。您获得的结果与您的指令完全相同。
为什么不工作?因为AngularJS中的范围使用原型继承。在父作用域上选择的值是一个基本。在JavaScript中,这意味着当子项设置相同的值时,它将被覆盖。在AngularJS范围中有一个黄金规则:模型值应该总是有一个。在他们中。也就是说,它们不应该是原语。有关详细信息,请参阅this SO answer。
这里是一个图片的范围初始看起来像。
单击第一项后,范围现在如下所示:
注意,在ngRepeat范围上创建了一个新的选定属性。控制器范围003未更改。
你可能猜到当我们点击第二个项目时会发生什么:
所以你的问题实际上不是由ngRepeat引起的 – 它是由打破AngularJS的黄金规则造成的。修复它的方法是简单地使用一个对象属性:
$scope.state = { selected: undefined };
<li ng-repeat="name in names" ng-class="{ active: $index == state.selected }" ng-click="state.selected = $index"> {{$index}}: {{name.first}} {{name.last}} </li>
这里是一个second JSFiddle显示这个作品太。
下面是最初的范围:
单击第一项后:
这里,根据需要影响控制器范围。
此外,为了证明这将仍然与你的指令隔离范围(因为,这与你的问题无关),这里是一个JSFiddle也是这样,视图必须反映该对象。你会注意到,唯一必要的改变是使用对象而不是原始。
范围最初:
点击第一项后的范围:
总结:再次,你的问题不是隔离范围,它不是如何ngRepeat工作。你的问题是,你打破了一个已知的规则,导致这个问题。 AngularJS中的模型应该总是有一个..