我正在寻找一些指南,可以用来帮助确定编写新指令时要使用的范围类型。理想情况下,我想要类似于流程图的内容,该流程将引导我解决一系列问题并弹出正确的答案-
没有新的新作用域,新的子作用域或新的孤立作用域-但这可能要求太多。这是我目前微不足道的准则集:
如果将使用指令的元素使用ng-model,请不要使用隔离范围。
如果指令不修改任何范围/模型属性,请不要创建新的范围
我知道在某个元素上使用具有隔离范围的指令会强制同一元素上的所有其他指令使用相同的(一个)隔离范围,因此在可以使用隔离范围时这不会严格限制吗?
我希望Angular-UI团队中的一些人(或编写了许多指令的其他人)可以分享他们的经验。
请不要添加简单回答“对可重用组件使用隔离范围”的答案。
真是个好问题!我很 喜欢 听别人怎么说,但这里是我使用的指导方针。
高海拔前提:作用域用作我们在父控制器,指令和指令模板之间进行通信的“胶水”。
父范围: scope: false
,因此完全没有新范围
我不经常使用它,但是正如@MarkRajcok所说,如果指令不访问任何范围变量(并且显然没有设置任何变量!),那么就我而言,这很好。这对于 仅
在父指令的上下文中使用的子指令(尽管总是有例外)并且没有模板也很有用。基本上,带有模板的任何东西都不属于共享范围,因为您本质上是在为访问和操作公开该范围(但我敢肯定,此规则有例外)。
例如,我最近创建了一个指令,该指令使用我在编写过程中使用的SVG库绘制(静态)矢量图形。它有$observe
两个属性(width
和height
),并在计算中使用这些属性,但它既没有设置也没有读取任何范围变量,也没有模板。这是不创建另一个范围的好用例。我们不需要一个,那为什么要麻烦呢?
但是,在另一个SVG指令中,我需要使用一组数据,并且还必须存储一点点状态。在这种情况下,使用父级作用域是不负责任的(同样,通常来说)。所以与其…
子范围: scope: true
带有子作用域的指令是上下文感知的,旨在与当前作用域进行交互。
显然,相对于隔离范围而言,此方法的主要优势在于,用户可以自由地对想要的任何属性使用插值;例如,class="item-type-{{item.type}}"
在具有隔离范围的指令上使用默认情况下将不起作用,但在具有子作用域的指令上可以正常使用,因为默认情况下仍可以在父作用域中找到内插的内容。同样,该指令本身可以在其自身范围内安全地评估属性和表达式,而不必担心父级污染或损坏。
例如,工具提示就是刚刚添加的内容;孤立范围将不起作用(默认情况下,请参见下文),因为期望我们在此使用其他指令或内插属性。工具提示只是一个增强。但是工具提示还需要在作用域上设置一些要与子指令和/或模板一起使用的东西,并且显然要管理其自身的状态,因此使用父作用域的确很不好。我们要么在污染它,要么在破坏它,布宜诺斯都没有。
我发现自己比隔离范围或父范围更经常使用子范围。
隔离范围: scope: {}
这是针对可重用组件的。:-)
但认真地说,我认为“可重用组件”是“自包含组件”。目的是将它们用于特定目的,因此将它们与其他指令结合或将其他内插属性固有地添加到DOM节点是没有意义的。
更具体地说,通过在父作用域的上下文中评估的指定属性,可以提供此独立功能所需的任何内容。它们可以是单向字符串(’@’),单向表达式(’&’)或双向变量绑定(’=’)。
在独立组件上,不需要在其上应用其他指令或属性,因为它本身就存在。它的样式由其自己的模板(如有必要)控制,并且可以包含适当的内容(如有必要)。它是独立的,因此我们将其放在一个单独的范围内也可以说:“不要对此烦恼。我通过这几个属性为您提供了已定义的API。”
最佳做法是从指令链接和控制器功能中排除尽可能多的基于模板的内容。这提供了另一个“类似于API”的配置点:指令的用户可以简单地替换模板!功能都保持不变,并且其内部API从未被使用过,但是我们可以根据需要尽可能地改变样式和DOM实现。ui
/ bootstrap是一个 很好的 例子,因为Peter&Pawel很棒。
隔离范围也非常适合与包含一起使用。带标签;它们不仅是全部功能,而且其 内部
的所有内容都可以在父范围内自由评估,同时让选项卡(和窗格)执行所需的任何操作。选项卡显然具有自己的 状态 ,该 状态
属于作用域(与模板进行交互),但是该状态与使用它的上下文无关-
它完全是使选项卡伪指令成为选项卡伪指令的内部。此外,在选项卡中使用任何其他指令没有太大意义。它们是选项卡-我们已经有了该功能!
将其包含更多功能或包含更多功能,但该指令已经存在。
综上所述,我应该注意,有一些方法可以解决隔离范围的某些限制(即功能),正如@ProLoser在他的回答中所暗示的那样。例如,在子作用域部分中,我提到了使用隔离作用域时(默认情况下)非定向属性中断时的插值。但是,例如,用户可以简单地使用class="item-type-{{$parent.item.type}}"
它,它将再次起作用。因此,如果迫切需要在子作用域上使用隔离作用域,但您担心其中一些限制,请知道您可以在需要时解决所有这些限制。
摘要
没有新作用域的指令为只读;他们是完全值得信赖的(即应用程序内部的),并且它们不会碰插孔。具有子作用域的指令可 添加 功能,但它们不是 唯一的
功能。最后,隔离范围是针对整个目标的指令;它们是独立的,因此可以让它们无赖(大多数“正确”)。
我想打消我的初衷,但是当我想到更多事情时,我将对其进行更新。但这真是太糟糕了-这样的答案很久了…
PS:完全切线,但是由于我们在讨论范围,所以我更喜欢说“原型”,而其他人则更喜欢“原型”,这似乎更准确,但是根本无法奏效。:-)
如果将使用指令的元素使用ng-model 请不要使用独立的作用域(请参见可以使用ng-model与独立的作用域吗?和 为什么格式化程序不能与独立作用域一起工作? 如果指令没有修改任何作用域/模型属性,则不要创建新的作用域 如果指令封装了一组DOM元素(文档中说“一个复杂的DOM结构”),并且该指令将作为一个元素使用,或者在同一元素上没有其他指令,那么隔离作用域似乎可以很好地工作。 我知道,在一个元
因此,我希望可以使用优先级来确保我的指令首先运行,并最终创建一个隔离范围,当运行时,它重用隔离范围,而不是创建一个原型上从父范围继承的范围。文档声明该指令在优先级下运行。尚不清楚是高优先级还是低优先级。当我在指令中使用优先级时,没有什么不同,所以我尝试了。但这使情况变得更糟:我的双向绑定变成,并且我的指令不显示任何内容。 我创造了一个小提琴来显示我的问题。我已经注释掉了指令中的设置。我有一个nam
问题内容: 给定带有transclude和隔离范围的指令(),当链接该指令时,我具有以下范围: 我期望: 如果同一指令具有 共享作用域 而不是 隔离作用域 ,则可以得到预期的结果。 这给我带来了一个问题,因为,如果被包含的内容包含另一个具有隔离范围的指令(),则会得到: 我想使用这样的指令: 但是,这并不工作,里面,是因为不上合适的范围。 我有两个问题: 如果指令具有隔离的作用域,为什么作用域不是
问题内容: 如何更新指令中的作用域? 我的指令: 单击后指令不会更新。 问题答案: 使用方法:
问题内容: 我正在寻找访问指令中“父”范围的任何方式。范围,超越,要求,从上方传入变量(或范围本身)的任何组合,等等。我完全愿意向后弯腰,但我想避免某些完全不可靠或难以维护的事情。例如,我知道我现在可以通过从preLink参数中获取并对其范围进行迭代以找到概念上的“父级” 来做到这一点。 重要说明 是,该指令必须在同一父范围内可重用。因此,默认行为(作用域:false)对我不起作用。我需要为指令的
问题内容: 我试图在我的指令中使用隔离范围放置一些默认值。基本上,绑定指令后,我需要使用scope对象进行一些DOM操作。下面是我的代码: 控制器: 服务: 指示: 自定义指令元素: 现在,问题是,当尝试在指令内部的默认方法中访问隔离范围时,我在获取数据并将其绑定到DOM的同时获得了未定义的值。如何访问广播侦听器中的隔离作用域并修改指令模板HTML?还有另一个处理这个的麻烦吗? 问题答案: 问题是