在AngularJS中编写指令时,如何确定是否不需要新的作用域,新的子作用域或新的隔离作用域? [英] When writing a directive in AngularJS, how do I decide if I need no new scope, a new child scope, or a new isolated scope?

查看:54
本文介绍了在AngularJS中编写指令时,如何确定是否不需要新的作用域,新的子作用域或新的隔离作用域?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一些指南,可以用来帮助确定编写新指令时要使用的范围类型.理想情况下,我想要类似于流程图的流程,该流程可以引导我解决一系列问题并弹出正确的答案–没有新的新范围,新的子范围或新的隔离范围–但这可能要求太多.这是我目前微不足道的指导原则:

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 through 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:

  • Don't use an isolated scope if the element that will use the directive uses ng-model
    See Can I use ng-model 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 documentation says "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 isolated 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?

我希望Angular-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 isolated 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.

高海拔前提:作用域用作我们在父控制器,指令和指令模板之间进行通信的胶水".

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.

父范围: scope: false,因此根本没有新的范围

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库绘制(静态)矢量图形.它具有$observe的两个属性(widthheight),并在其计算中使用这些属性,但是它既没有设置也没有读取任何范围变量,也没有模板.这是不创建另一个范围的好用例.我们不需要一个,那为什么要麻烦呢?

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...

儿童范围: scope: true

具有子范围的指令是上下文感知的,旨在与当前范围进行交互.

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

很明显,与孤立范围相比,此方法的关键优势在于用户可以自由地对所需的任何属性使用插值;例如在具有隔离范围的指令上使用class="item-type-{{item.type}}"在默认情况下将不起作用,但在具有子范围的指令上可以正常使用,因为默认情况下仍可以在父范围中找到内插的内容.此外,该指令本身可以在其自身范围内安全地评估属性和表达式,而不必担心对父代的污染或损坏.

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.

隔离范围:scope: {}

这是针对可重用组件的. :-)

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.

更具体地说,通过在父作用域的上下文中评估的指定属性来提供此独立功能所需的任何内容;它们是单向字符串('@'),单向表达式('&')或两向变量绑定('=').

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 ('=').

在独立组件上,没有必要在其上应用其他指令或属性,因为它们本身就存在.它的样式由其自己的模板(如有必要)控制,并且可以包含适当的内容(如有必要).它是独立的,因此我们将其放在一个单独的范围内也可以说:不要对此烦恼.我通过这几个属性为您提供了已定义的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/bootstrap是一个很好的例子,因为彼得& Pawel很棒.

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.

隔离范围也非常适合与包含一起使用.采取制表符;它们不仅是全部功能,而且内部中的任何内容都可以在父范围内自由评估,同时让选项卡(和窗格)执行所需的任何操作.选项卡显然具有自己的 state ,该状态属于作用域(与模板进行交互),但是该状态与使用它的上下文无关-它完全是内部的选项卡指令选项卡指令.此外,在选项卡中使用任何其他指令都没有多大意义.它们是选项卡-我们已经有了该功能!

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!

以更多功能包围或包含更多功能,但是指令已经存在.

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

所有这些,我应该指出,有一些方法可以解决隔离范围的某些限制(即功能),就像@ProLoser在他的回答中所暗示的那样.例如,在子作用域部分中,我提到了使用隔离作用域时(默认情况下)非定向属性中断的插值.但是,例如,用户可以简单地使用class="item-type-{{$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.

摘要

没有新作用域的指令为只读;他们是完全受信任的(即在应用内部),并且他们不会碰插孔.具有子作用域 add 功能的指令,但它们不是唯一的功能.最后,隔离范围是针对整个目标的指令;它们是独立的,因此可以让它们无赖(大多数正确").

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.

我想表达我的最初想法,但是当我想到更多事情时,我将对其进行更新.但这真是个烂话-这么一个答案很久了...

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:完全是切线的,但是由于我们在谈论范围,所以我更喜欢说原型",而其他人则喜欢原型",这似乎更准确,但是根本无法奏效. :-)

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天全站免登陆