AngularJS:当编写一个指令,我怎么决定,如果需要没有新的范围,一个新的子范围,或新的分离范围是什么? [英] AngularJS : When writing a directive, how do I decide if a need no new scope, a new child scope, or a new isolate scope?

查看:172
本文介绍了AngularJS:当编写一个指令,我怎么决定,如果需要没有新的范围,一个新的子范围,或新的分离范围是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在找一些指导,人们可以用它来帮助确定的范围类型编写一个新的指令时使用的。理想情况下,我想类似走我虽然一大堆的问题,突然迸出了正确的答案&ndash的流程图的东西;没有新的新范畴,新的子范围,或新的分离范围&ndash的;但是这很可能要求太高。这是我目前的微不足道的一套准则:

I'm looking for some guidelines that one can use to help determine which type of scope to use when writing a new directive. Ideally, I'd like something similar to a flowchart that walks me though a bunch of questions and out pops the correct answer – no new new scope, new child scope, or new isolate scope – but that is likely asking for too much. Here's my current paltry set of guidelines:


    如果将使用该指令,元件使用NG-模型
  • 请不要使用分离范围
    结果请参见 ngModel和孤立的范围并搜索<组件href=\"http://stackoverflow.com/questions/14495882/why-formatters-does-not-work-with-isolated-scope\">Why格式化并不孤立范围工作?

  • 如果该指令不修改任何范围/模特属性,不创建一个新的作用域

  • 隔离范围似乎运作良好,如果指令封装了一组DOM元素(的文档说:一个复杂的DOM结构)和指令将被用作一个元素,或具有相同的元件上没有其他的指令

  • don't use an isolate scope if the element that will use the directive uses ng-model
    See ngModel and component with isolated scope and
    Why formatters does not work with isolated scope?
  • if the directive doesn't modify any scope/model properties, don't create a new scope
  • isolate scopes seem to work well if the directive is encapsulating a set of DOM elements (the docs say "a complex DOM structure") and the directive will be used as an element, or with no other directives on the same element

我知道,使用一个指令与一个元件上的分离范围迫使该相同元件上的所有其他指令,以使用相同的(一个)隔离范围,所以不会这严重限制时,可以使用的分离物范围?

I'm aware that using a directive with an isolate scope on an element forces all other directives on that same element to use the same (one) isolate scope, so doesn't this severely limit when an isolate scope can be used?

我希望一些来自角UI团队(或者其他人已经写了许多指令)可以分享他们的经验。

I am hoping that some from the Angular-UI team (or others that have written many directives) can share their experiences.

请不要添加一个答案只是说使用分离的余地可重用的组件。

Please don't add an answer that simply says "use an isolate scope for reusable components".

推荐答案

真是一个伟大的问题!我最好的的听听别人怎么说,但这里是我使用的指导原则。

What a great question! I'd love to hear what others have to say, but here are the guidelines I use.

的高空premise:范围被用作胶水,我们使用父控制器,该指令和该指令的模板之间的通信

The high-altitude premise: scope is used as the "glue" that we use to communicate between the parent controller, the directive, and the directive template.

父范围: 范围:假,所以根本没有新的范围

Parent Scope: scope: false, so no new scope at all

我不经常使用这个,但作为@MarkRajcok表示,如果指令不访问任何范围变量(显然不设置任何!),那么这仅仅是罚款,据我所关注的。这也是被的的用于在父指令的背景下,子指令有帮助(尽管总有例外)和不具有一个模板。基本上与模板任何不属于共享范围,因为你本身是公开的范围访问和操作(但我敢肯定,有此规则的例外)。

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库我写作的过程就是一个(静态)矢量图形指令。它 $观察的两个属性(宽度高度)并使用那些在它的计算,但它没有,也没有设置任何读取范围的变量,没有模板。这是一个很好的用例没有创造另一个范围;我们并不需要一个,何必呢?

As an example, I recently created a directive that draws a (static) vector graphic using an SVG library I'm in the process of writing. It $observes two attributes (width and height) and uses those in its calculations, but it neither sets nor reads any scope variables and has no template. This is a good use case for not creating another scope; we don't need one, so why bother?

但在另一个SVG指令,但是,我需要的一组数据来使用,另外不得不存储状态的一点点。在这种情况下,使用父范围将是不负责任(再次,一般来说)。因此,而不是...

But in another SVG directive, however, I required a set of data to use and additionally had to store a tiny bit of state. In this case, using the parent scope would be irresponsible (again, generally speaking). So instead...

儿童适用范围: 范围:真正的

的小孩范围指令是上下文感知的,旨在与当前范围内进行互动。

Directives with a child scope are context-aware and are intended to interact with the current scope.

显然,这样通过一个分离范围主要优势是,用户可以自由地在任何他们想要的属性使用插值;例如使用类=项类型 - {{项目。形式}}与一个分离范围指令将默认情况下不工作,但在一个正常工作与孩子范围,因为无论是插仍然可以通过默认父范围内被发现。此外,该指令本身可以安全地评估其自身的范围的上下文属性和前pressions无需担心污染或损坏到母体

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.

我发现自己使用儿童范围往往比孤立或父作用域。

I find myself using child scopes more often than isolate or parent scopes.

隔离范围: 范围:{}

这是可重用的组件。 :-)

This is for reusable components. :-)

但严重的是,我认为可重用组件为自我包含的组件的。的意图是,它们是用于特定的目的,所以它们与其他指令组合或添加其他内插的属性对DOM节点固有没有意义。

But seriously, I think of "reusable components" as "self-contained components". The intent is that they are to be used for a specific purpose, so combining them with other directives or adding other interpolated attributes to the DOM node inherently doesn't make sense.

要更具体,需要为这个独立的任何功能是通过在父范围的上下文中计算指定属性提供的;它们或者单向的字符串(@),单向离pressions('和;'),或双向可变绑定(=)。

To be more specific, anything needed for this standalone functionality is provided through specified attributes evaluated in the context of the parent scope; they are either one-way strings ('@'), one-way expressions ('&'), or two-way variable bindings ('=').

在自包含组件,它是没有意义的,以需要应用其他指令或因为它的存在本身就可以了属性。其风格是由它自己的模板支配(如有必要),并且可以有适当的内容transcluded(如有必要)。它是独立的,所以我们把它放在一个隔离的范围也说:。与此不惹我给你通过这几个属性的定义的API

On self-contained components, it doesn't make sense to need to apply other directives or attributes on it because it exists by itself. Its style is governed by its own template (if necessary) and can have the appropriate content transcluded (if necessary). It's standalone, so we put it in an isolate scope also to say: "Don't mess with this. I'm giving you a defined API through these few attributes."

一个很好的最佳做法是从指令链路和控制器的功能尽可能排除尽可能多的基于模板的东西。这提供了另一种API状配置上看:该指令的用户只需更换模板!该功能都保持不变,其内部API是从未接触过,但我们可以惹的造型和DOM实现尽可能多的,因为我们需要。 UI /引导是的如何做好这一点,因为彼得放伟大的例子。帕维尔是真棒。

A good best practice is to exclude as much template-based stuff from the directive link and controller functions as possible. This provides another "API-like" configuration point: the user of the directive can simply replace the template! The functionality all stayed the same, and its internal API was never touched, but we can mess with styling and DOM implementation as much as we need to. ui/bootstrap is a great example of how to do this well because Peter & Pawel are awesome.

隔离范围也非常适合与transclusion使用。就拿标签;他们不仅是全功能的,但无论是的的它可以自由地从父范围之内,同时使标签(和窗格),以为所欲为评估。这些标签显然有自己的状态的,属于上范围(与模板交互),但该国已无关,与在它被使用的上下文 - 这是完全内部是什么原因使标签指令标签指令。此外,它并没有多大意义,使用任何其他指令的标签。他们是标签 - 我们已经有了这个功能。

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!

具有更多功能围绕着它或transclude更多的功能,但该指令是它是什么了。

Surround it with more functionality or transclude more functionality, but the directive is what it is already.

所有这一切说,我要指出,周围有一些限制的范围分离的(即特征)的方式,为@ProLoser暗示在他的回答。例如,在孩子的范围中,我提到在非指令属性的使用范围隔离(默认),当断插值。但是,用户可以,例如,简单地使用类=项类型 - {{$ parent.item.type}}键,它会再次工作。所以,如果有一个令人信服的理由了孩子范围使用隔离范围,但你担心这些局限性,知道你可以解决几乎所有的人,如果你需要。

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.

摘要

没有新范围指令是只读的;他们完全信赖​​(即内部的应用程序),他们不接触插孔。与儿童范围指令的添加的功能,但它们都没有的唯一的功能。最后,隔离范围是为那些在整个目标指令;他们是独立的,所以它的好(最正确),让他们去流氓。

Directives with no new scope are read-only; they're completely trusted (i.e. internal to the app) and they don't touch jack. Directives with a child scope add functionality, but they are not the only functionality. Lastly, isolate scopes are for directives that are the entire goal; they are standalone, so it's okay (and most "correct") to let them go rogue.

我希望得到我最初的想法,但是我觉得更多的东西,我会及时更新。但哇靠 - 这是漫长的一个SO回答...

I wanted to get my initial thoughts out, but as I think of more things, I'll update this. But holy crap - this is long for an SO answer...

PS:完全切,但由于我们正在谈论的范围,我preFER说原型,而其他preFER原型,这似乎是更准确,但只是推出了舌头不在所有的好。 : - )

PS: Totally tangential, but since we're talking about scopes, I prefer to say "prototypical" whereas others prefer "prototypal", which seems to be more accurate but just rolls off the tongue not at all well. :-)

这篇关于AngularJS:当编写一个指令,我怎么决定,如果需要没有新的范围,一个新的子范围,或新的分离范围是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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