指令隔离在AngularJS NG重复范围范围(Directive isolate scope wi

2019-07-23 08:04发布

我有一个隔离范围的一个指令(这样我就可以重新使用在其他地方的指令),当我使用这个指令与ng-repeat ,它不能正常工作。

我已阅读所有的文件和堆栈溢出有关这个主题的答案和理解问题。 我相信我已经避免所有常见的陷阱。

所以,我明白,我的代码失败,因为创建范围的ng-repeat指令。 我自己的指令创建一个隔离范围的和做了双向数据绑定到父范围的对象。 我的指令将一个新的对象赋值给这个绑定变量,这完美的作品时,我的指令,而不采用ng-repeat (父变量正确更新)。 然而, ng-repeat ,分配在创建一个新的变量ng-repeat范围和父变量没有看到变化。 所有这一切都基于我所读的预期。

我也看到,当有一个给定的元素上的多个指令,只创建一个范围。 和一个priority可以在每个指令来定义,其中所应用的指令的顺序来设置; 该指令按优先级排序,然后自己编译函数被调用(在搜索词优先http://docs.angularjs.org/guide/directive )。

所以,我希望我能优先使用,以确保我的指令,第一个运行,并最终建立一个隔离范围的,当ng-repeat运行时,它重新采用分离范围的,而不是创建prototypically从继承的范围父范围。 在ng-repeat文件指出,该指令在优先级运行1000 。 目前尚不清楚是否1是更高的优先级或更低的优先级水平。 当我使用的优先级1在我的指令,它没有发挥作用,所以我尝试2000 。 但是,这使事情变得更糟:我的双向绑定变得undefined ,我的指令不显示任何内容。

我创建了一个小提琴显示我的问题 。 我注释掉的priority在我的指令设置。 我的名字对象的列表和指令叫name-row ,显示的名字对象的名字和姓氏的字段。 当点击所显示的名字,我想它设置一个selected变量主要适用范围。 名称的阵列,所述selected变量被传递到name-row使用双向数据绑定指令。

我知道如何通过在主范围内调用函数来得到这个工作。 我也知道,如果selected是另一个对象里面,我绑定到外部对象,事情会工作。 但我不感兴趣,目前这些解决方案。

相反,我有问题是:

  • 如何防止ng-repeat从创建prototypically从父范围继承的范围,而是把它用我的指令的分离,范围有多大?
  • 为什么是优先级2000在我的指令不能正常工作?
  • 使用Batarang,是有可能知道正在使用什么类型的范围是什么?

Answer 1:

好了,通过大量的上述评论的,我已经发现了混乱。 首先,一对夫妇澄清几点:

  • ngRepeat不会影响你的选择范围隔离
  • 传递到ngRepeat为您指令的属性使用该参数使用prototypically继承范围
  • 你的指令无法正常工作的原因无关与分离范围

下面是相同的代码,但是去除了该指令的例子:

<li ng-repeat="name in names"
    ng-class="{ active: $index == selected }"
    ng-click="selected = $index">
    {{$index}}: {{name.first}} {{name.last}}
</li>

这里是一个的jsfiddle证明,认为它不会工作。 你得到同样的结果在你的指令。

为什么不工作? 因为在AngularJS范围使用原型继承。 价值selected上你的父母范围是一种原始的 。 在JavaScript中,这意味着,当孩子套相同的值将被覆盖。 有一个在AngularJS范围金科玉律:模型值应该始终有一个. 在他们中。 也就是说,他们不应该是原语。 见这个苏答案以获取更多信息。


这是一个什么样的范围最初看起来像一个图片。

单击第一个项目后,该作用域现在这个样子:

请注意,新selected财产在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>

这里是一个第二的jsfiddle显示这个工程太。

这里是示波器的样子开始:

单击第一个项目后:

这里,控制器范围受到影响,如需要的话。

此外,为了证明这仍然会与你的指令工作与分离范围(因为,同样,这无关你的问题),这里是一个的jsfiddle也太,认为必须反映的对象。 你会注意到,只需要改变为使用对象 ,而不是原始的。

作用域开始:

点击第一个项目之后的范围:

总之:再次,你的问题是不是与分离的范围,这是不是与ngRepeat是如何工作的。 你的问题是,你打破,是已知的导致这个问题非常的规则。 在AngularJS模型应该始终有一个.



Answer 2:

如果没有直接试图避免回答你的问题,而不是看看下面的小提琴:

http://jsfiddle.net/dVPLM/

关键的一点是,而不是试图争取和改变角度的常规行为,你可以组织你的指令一起工作ng-repeat ,而不是试图将其覆盖。

在您的模板:

    <name-row 
        in-names-list="names"
        io-selected="selected">
    </name-row>

在你的指令:

    template:
'        <ul>' +      
'            <li ng-repeat="name in inNamesList" ng-class="activeClass($index)" >' +
'                <a ng-click="setSelected($index)">' +
'                    {{$index}} - {{name.first}} {{name.last}}' +
'                </a>' +
'            </li>' +
'        </ul>'

在回答你的问题:

  • ng-repeat将创建一个范围,你真的不应该试图改变这一点。
  • 优先指令不仅仅是执行顺序-见: AngularJS:如何在HTML编译安排编制的顺序?
  • 在Batarang,如果选中性能标签,你可以看到开往各范围的表述,并检查是否符合这个您的期望。


文章来源: Directive isolate scope with ng-repeat scope in AngularJS