AngularJS:指令隔离带范围NG-重复范围 [英] AngularJS : Directive isolate scope with ng-repeat scope

查看:184
本文介绍了AngularJS:指令隔离带范围NG-重复范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a directive with an isolate-scope (so that I can reuse the directive in other places), and when I use this directive with an ng-repeat, it fails to work.

我看了所有的文档和StackOverflow上关于这一主题的答案和理解问题。我相信我已经避免了所有常见的陷阱。

I have read all the documentation and stackoverflow answers on this topic and understand the issues. I believe I have avoided all the usual gotchas.

所以,我明白我的code失败,因为由 NG-重复指令创建的范围。您自己的指令创建一个分离物,范围和做了双向数据绑定到父范围的对象。我的指令将一个新的对象赋值给这个绑定的变量,这完美的作品时,我的指令用于无 NG-重复(父变量正确更新)。然而,随着 NG-重复,分配会在 NG-重复作用域的新变量,父变量不没有看到改变。所有这一切都为基于我读过的预期。

So I understand that my code fails because of the scope created by the ng-repeat directive. My own directive creates an isolate-scope and does a two-way data-binding to an object in the parent scope. My directive will assign a new object-value to this bound variable and this works perfectly when my directive is used without ng-repeat (the parent variable is updated correctly). However, with ng-repeat, the assignment creates a new variable in the ng-repeat scope and the parent variable does not see the change. All this is as expected based on what I have read.

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

I have also read that when there are multiple directives on a given element, only one scope is created. And that a priority can be set in each directive to define the order in which the directives are applied; the directives are sorted by priority and then their compile functions are called (Search for the word priority at http://docs.angularjs.org/guide/directive).

所以,我希望我能优先使用,以确保我的指令第一次运行,并最终建立一个隔离范围的,而当 NG-重复运行,它将重新-uses的分离范围的,而不是创建中典型从父范围继承的范围。在 NG-重复文件指出,该指令在优先级运行 1000 。目前尚不清楚是否 1 是一个更高的优先级或低优先级。当我使用的优先级 1 在我的指令,它没有有所作为,所以我试图 2000 。但是,这使事情变得更糟。我的双向绑定成为未定义和我的指令不显示任何内容。

So I was hoping I could use priority to make sure that my directive runs first and ends up creating an isolate-scope, and when ng-repeat runs, it re-uses the isolate-scope instead of creating a scope that prototypically inherits from the parent scope. The ng-repeat documentation states that that directive runs at priority level 1000. It is not clear whether 1 is a higher priority level or a lower priority level. When I used priority level 1 in my directive, it did not make a difference, so I tried 2000. But that makes things worse: my two-way bindings become undefined and my directive does not display anything.

我创建了一个小提琴显示我的问题。我已经注释掉在我的指令优先设置。我的名字对象的列表和一个名为名行指令,显示在名称对象的名字和姓氏的字段。当单击显示的名称,我想它设置了在主范围内选择变量。名称数组中,变量传递给的名字排采用双向数据绑定指令。

I have created a fiddle to show my issue. I have commented out the priority setting in my directive. I have a list of name objects and a directive called name-row that shows the first and last name fields in the name object. When a displayed name is clicked, I want it to set a selected variable in the main scope. The array of names, the selected variable are passed to the name-row directive using two-way data-binding.

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

I know how to get this to work by calling functions in the main scope. I also know that if selected is inside another object, and I bind to the outer object, things would work. But I am not interested in those solutions at the moment.

相反,我有问题是:


  • 如何prevent NG-重复从创建中典型从父作用域继承的范围,而是把它用我的指令的分离范围的<? / LI>
  • 为什么是优先级 2000 在我的指令不工作?

  • 使用Batarang,才可能知道正在使用什么类型的范围是什么?

  • How do I prevent ng-repeat from creating a scope that prototypically inherits from the parent scope, and instead have it use my directive's isolate-scope?
  • Why is priority level 2000 in my directive not working?
  • Using Batarang, is it possible to know what type of scope is in use?

推荐答案

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

Okay, through a lot of the comments above, I have discovered the confusion. First, a couple of points of clarification:


  • ngRepeat不会影响你的选择范围隔离

  • 传递到ngRepeat上使用您的指令的属性参数的的使用中典型继承范围

  • 您的指令不能正常工作的原因无关与分离范围

  • ngRepeat does not affect your chosen isolate scope
  • the parameters passed into ngRepeat for use on your directive's attributes do use a prototypically-inherited scope
  • the reason your directive doesn't work has nothing to do with the isolate scope

下面是同样的code的一个例子,但该指令删除:

Here's an example of the same code but with the directive removed:

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

下面是一个的jsfiddle 的证明,这是行不通的。你得到同样的结果在你的指令。

Here is a JSFiddle demonstrating that it won't work. You get the exact same results as in your directive.

为什么它不工作?因为在AngularJS范围使用原型继承。该值你的父母范围是一个原始即可。在JavaScript中,这意味着,当一个子集相同的值,将被覆盖。有一个在AngularJS范围金科玉律:模型值应总是的有 在其中。也就是说,他们不应该是原语。请参见这个SO回答了解详情。

Why doesn't it work? Because scopes in AngularJS use prototypical inheritance. The value selected on your parent scope is a primitive. In JavaScript, this means that it will be overwritten when a child sets the same value. There is a golden rule in AngularJS scopes: model values should always have a . in them. That is, they should never be primitives. See this SO answer for more information.

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

Here is a picture of what the scopes initially look like.

单击第一个项目后,作用域现在看起来是这样的:

After clicking the first item, the scopes now look like this:

请注意,新的财产上ngRepeat范围内创建。控制器范围003没有改变。

Notice that a new selected property was created on the ngRepeat scope. The controller scope 003 was not altered.

您可能已经猜到了,当我们点击第二项会发生什么:

You can probably guess what happens when we click on the second item:

所以你的问题实际上是不被ngRepeat都造成 - 它打破在AngularJS金科玉律引起的。解决它的方法是简单地使用一个对象属性:

So your issue is actually not caused by ngRepeat at all - it's caused by breaking a golden rule in AngularJS. The way to fix it is to simply use an object property:

$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 呈现这个作品了。

Here is a second JSFiddle showing this works too.

下面是示波器的样子开始:

Here is what the scopes look like initially:

单击第一个项目之后:

下面,控制器范围被影响,因为所需的

Here, the controller scope is being affected, as desired.

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

Also, to prove that this will still work with your directive with an isolate scope (because, again, this has nothing to do with your problem), here is a JSFiddle for that too, the view must reflect the object. You'll note that the only necessary change was to use an object instead of a primitive.

最初的作用域:

斯科普斯点击第一个项目后:

Scopes after clicking on the first item:

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

To conclude: once again, your issue isn't with the isolate scope and it isn't with how ngRepeat works. Your problem is that you're breaking a rule that is known to lead to this very problem. Models in AngularJS should always have a ..

这篇关于AngularJS:指令隔离带范围NG-重复范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆