多好的问题啊!我很想听听别人怎么说,但这里是我使用的指导方针。
高度前提:作用域被用作父控制器、指令和指令模板之间通信的“胶水”。
父作用域:作用域:false,因此根本没有新的作用域
I don't use this very often, but as @MarkRajcok said, if the directive doesn't access any scope variables (and obviously doesn't set any!) then this is just fine as far as I am concerned. This is also helpful for child directives that are only used in the context of the parent directive (though there are always exceptions to this) and that don't have a template. Basically anything with a template doesn't belong sharing a scope, because you are inherently exposing that scope for access and manipulation (but I'm sure there are exceptions to this rule).
举个例子,我最近创建了一个指令,使用我正在编写的SVG库绘制(静态)矢量图形。它$观察两个属性(宽度和高度),并在计算中使用它们,但它既不设置也不读取任何作用域变量,也没有模板。这是一个不创建另一个作用域的好用例;我们不需要,那又何苦呢?
但是,在另一个SVG指令中,我需要使用一组数据,另外还必须存储一小部分状态。在这种情况下,使用父作用域是不负责任的(同样,一般来说)。所以…
子范围:范围:true
具有子作用域的指令是上下文感知的,用于与当前作用域交互。
Obviously, a key advantage of this over an isolate scope is that the user is free to use interpolation on any attributes they want; e.g. using class="item-type-{{item.type}}" on a directive with an isolate scope will not work by default, but works fine on one with a child scope because whatever is interpolated can still by default be found in the parent scope. Also, the directive itself can safely evaluate attributes and expressions in the context of its own scope without worrying about pollution in or damage to the parent.
For example, a tooltip is something that just gets added; an isolate scope wouldn't work (by default, see below) because it is expected that we will use other directives or interpolated attributes here. The tooltip is just an enhancement. But the tooltip also needs to set some things on the scope to use with a sub-directive and/or template and obviously to manage its own state, so it would be quite bad indeed to use the parent scope. We are either polluting it or damaging it, and neither is bueno.
我发现自己更多地使用子作用域而不是孤立作用域或父作用域。
隔离范围:范围:{}
这是针对可重用组件的。: -)
但是认真地说,我认为“可重用组件”是“自包含组件”。其目的是将它们用于特定目的,因此将它们与其他指令组合或向DOM节点添加其他内插属性本质上是没有意义的。
更具体地说,这个独立功能所需的任何东西都是通过在父作用域上下文中计算的指定属性来提供的;它们要么是单向字符串('@'),要么是单向表达式('&'),要么是双向变量绑定('=')。
在自包含组件上,需要对其应用其他指令或属性是没有意义的,因为它本身就存在。它的样式由它自己的模板管理(如果需要),并且可以包含适当的内容(如果需要)。它是独立的,所以我们把它放在一个孤立的范围内,也就是说:“不要搞砸它。我通过这几个属性给你一个定义好的API。”
一个好的最佳实践是将尽可能多的基于模板的东西从指令链接和控制器函数中排除。这提供了另一个“类似api”的配置点:指令的用户可以简单地替换模板!所有的功能都保持不变,其内部API从未被改变,但我们可以随心所欲地改变样式和DOM实现。ui/bootstrap是如何做到这一点的一个很好的例子,因为Peter和Pawel很棒。
Isolate scopes are also great for use with transclusion. Take tabs; they are not only the whole functionality, but whatever is inside of it can be evaluated freely from within the parent scope while leaving the tabs (and panes) to do whatever they want. The tabs clearly have their own state, which belongs on the scope (to interact with the template), but that state has nothing to do with the context in which it was used - it's entirely internal to what makes a tab directive a tab directive. Further, it doesn't make much sense to use any other directives with the tabs. They're tabs - and we already got that functionality!
用更多的功能包围它,或者渗透更多的功能,但指令已经是这样了。
All that said, I should note that there are ways around some of the limitations (i.e. features) of an isolate scope, as @ProLoser hinted at in his answer. For example, in the child scope section, I mentioned interpolation on non-directive attributes breaking when using an isolate scope (by default). But the user could, for example, simply use class="item-type-{{$parent.item.type}}" and it would once again work. So if there is a compelling reason to use an isolate scope over a child scope but you're worried about some of these limitations, know that you can work around virtually all of them if you need to.
总结
没有新的作用域的指令是只读的;他们是完全可信的(即在应用程序内部),他们不接触任何东西。带有子作用域的指令增加了功能,但它们不是唯一的功能。最后,隔离作用域用于作为整个目标的指令;它们是独立的,所以让它们失控是可以的(也是最“正确的”)。
我想把我最初的想法说出来,但当我想到更多的事情时,我会更新这个。但我的天-这是一个很长的SO答案…
PS:完全离题,但既然我们在谈论范围,我更喜欢说“原型”,而其他人更喜欢说“原型”,这似乎更准确,但只是从舌头上滑下来,一点也不好。: -)