AngularJS:为什么ng-bind在角度上比{{}}好?


401

我参加了一次有角度的演讲,会议中提到的一位参加者ng-bind胜于{{}}束缚。

原因之一是ng-bind将变量放在监视列表中,并且仅当发生模型更改时,才将数据推送到视图中查看;另一方面,{{}}每次都会对表达式进行插值(我想这是角周期)并推送值,即使值更改与否。

也有人说,如果屏幕上没有太多数据,则可以使用{{}},并且性能问题将不可见。有人可以帮我阐明一下这个问题吗?



3
您能否检查一下,如果我的答案更好
Konstantin Krass 2015年

我认为{{}}不切实际,查看者会在数据完全加载之前看到您的标签。我想知道Angular团队是否会解决此问题。
杰里·梁

2
@Blazemonger:难道不能只包含ng-cloak属性以防止模板立即显示吗?
supershnee

Answers:


322

如果您没有使用ng-bind,则类似以下内容:

<div>
  Hello, {{user.name}}
</div>

您可能会Hello, {{user.name}}user.name解决之前(在加载数据之前)看到一秒钟的实际值

你可以做这样的事情

<div>
  Hello, <span ng-bind="user.name"></span>
</div>

如果这对您来说是个问题。

另一个解决方案是使用ng-cloak


3
根据您所说的内容,如果使用{{}}不会对性能产生影响?有人告诉我,如果每次使用{{}},即使模型没有更改,也会被插入并生成结果。
Nair

4
如果我不想在span标签内包装user.name,如何使用ng-bind?如果我使用大括号,我会得到干净的名字,没有html标签
Victor,

5
@KevinMeredith加载HTML时看起来像这样,但是角度还没有。请记住,我们正在谈论的是客户端模板。所有插值都必须在加载应用的浏览器中完成。通常,角负载足够快以至于不会引起注意,但在某些情况下会成为问题。因此,ng-cloak被发明来修补这个问题。
全息原理

17
对我来说,这不是问题的答案,为什么ngBind更好。这就是使用ngBind代替{{}}批注和对ngCloak的引用的方法。
康斯坦丁·克拉斯

4
@Victor还有ng-bind-template两种方法可以结合使用:ng-bind-template="Hello, {{user.name}}"在这里,绑定仍然可以提高性能,并且不引入任何进一步的嵌套
舒适

543

能见度:

当您的angularjs启动时,用户可能会在html中看到您放置的括号。可以使用来处理ng-cloak。但对我来说,这是一种变通方法,如果我使用的话,则不需要使用ng-bind


性能:

{{}}慢得多

ng-bind是一条指令,它将在传递的变量上放置观察者。因此,ng-bind仅当传递的值确实发生更改时,才会应用。

在另一方面括号将脏检查,并刷新在每一个 $digest,即使是没有必要的


我目前正在构建一个大型单页应用程序(每个视图约500个绑定)。从{{}}更改为strict ng-bind确实可以为我们节省大约20%的费用scope.$digest


建议

如果您使用诸如angular-translate之类的转换模块,则始终在方括号注释之前首选伪指令

{{'WELCOME'|translate}} => <span ng-translate="WELCOME"></span>

如果需要过滤器功能,最好选择一个指令,该指令实际上只是使用您的自定义过滤器。 $ filter服务的文档


2014年11月28日更新(但可能不在主题范围内):

在Angular 1.3x bindonce中引入了功能。因此,您可以一次绑定一个表达式/属性的值(当!='undefined'时将被绑定)。

当您不希望绑定更改时,这很有用。

用法:::在装订前放置:

<ul>  
  <li ng-repeat="item in ::items">{{item}}</li>
</ul>  
<a-directive name="::item">
<span data-ng-bind="::value"></span>

例:

ng-repeat在表中输出一些数据,每行具有多个绑定。翻译绑定,过滤器输出,将在每个作用域摘要中执行。


32
这是一个更好的答案
NimChimpsky 2014年

13
据我所知(截至2014-11-24),卷曲插值的处理方式与指令相同(请参见ng / compile.js中的addTextInterpolateDirective())。它还使用$ watch,因此如果文本不变,不会触及DOM,并且不会像您声明的那样在每个$ digest上“脏检查并刷新”它。但是,对每个$ digest执行的操作是计算插值结果字符串。除非更改,否则不会将其分配给文本节点。
Matti Virkkunen 2014年

6
我编写了用于内部评估的性能测试。它在ng重复中有2000个条目,并在对象中显示2个属性,因此为2000x2绑定。绑定的不同之处在于:第一个绑定只是跨度中的绑定。秒内有一个绑定和一些普通的html。结果:ng-bind速度更快,适用每个范围约20%。如果不检查代码,似乎在html元素中带有卷曲表达式的其他纯html会花费更多时间。
Konstantin Krass 2014年

2
只想指出一点,根据这里的测试:jsperf.com/angular-bind-vs-brackets似乎表明括号比绑定要快。(注意:小节是每秒的操作数,因此越长越好)。正如前面的评论所指出的,它们的监视机制最终是相同的。
沃伦2014年

1
因为您没有提供任何来源,所以我给您一个:ng-perf.com/2014/10/30/… “ ng-bind更快,因为它更简单。插值必须经过验证上下文,JSON格式化的额外步骤值等等。这会使它变慢。”
康斯坦丁·克拉斯

29

ng-bind 胜过 {{...}}

例如,您可以这样做:

<div>
  Hello, {{variable}}
</div>

这意味着将Hello, {{variable}}包围其中的整个文本<div>并将其存储在内存中。

相反,如果您执行以下操作:

<div>
  Hello, <span ng-bind="variable"></span>
</div>

仅该值的值将存储在内存中,而angular将注册仅包含变量的监视程序(监视表达式)。


7
另一方面,您的DOM更深入。根据您的操作,在大文档中这可能会影响渲染性能。
stephband

2
是的,我认为@stephband也是如此。例如,如果您只想显示姓名和姓氏。为什么不只是插值?它将执行相同的方式,因为它将在1个摘要中运行相同的手表。像:<div> {{firstname}} {{lastName}} </ div> == <div> <span ng-bind =“ firstName”> </ span> <span ng-bind =“ lastName”> </ span> </ div> ..第一个看起来更好。我认为这在很大程度上取决于您要什么,但最终它们都有优点和缺点。
pgarciacamou 2014年

3
<div ng-bind-template="{{ var1 }}, {{ var2}}"></div>是{{}}的替代方法,功能类似于ng-bind
northamerican 2015年

1
这不是苹果对苹果-您要在一个而不是另一个中引入span元素。的示例ng-bind将与更具可比性<div>Hello, <span>{{variable}}</span></div>
iconoclast

15

基本上,double-curly语法更自然易读,并且需要更少的键入。

两种情况都产生相同的输出,但是..如果您选择继续使用{{}},则用户可能会看到几毫秒的时间,{{}}然后才能通过角度渲染模板。因此,如果您发现有任何{{}}更好的用法ng-bind

同样非常重要的是,只有在角度应用程序的index.html中,您才能取消渲染{{}}。如果使用指令,则使用模板,那么就没有机会看到它,因为angular首先渲染模板,然后将其附加到DOM。


5
有趣的是,它并不相同。我在ng-bind =“ anArrayViaFactory”与{{anArrayViaFactory}}上没有任何输出。尝试在jekyll原型中输出json响应时遇到了这个问题,但是由于与类似模板{{}}的冲突,我被迫使用ng-bind。ng-repeat块(anArrayViaFactory中的项目)内的ng-bind将输出值。
eddywashere 2014年

5

{{...}}是指双向数据绑定。但是,ng-bind实际上是用于单向数据绑定的。

使用ng-bind将减少您页面中观察者的数量。因此ng-bind将比快{{...}}。因此,如果您只想显示一个值及其更新,并且不想将其更改从UI反映回控制器,那么请使用ng-bind。这将提高页面性能并减少页面加载时间。

<div>
  Hello, <span ng-bind="variable"></span>
</div>

4

这是因为使用{{}}角度编译器会同时考虑文本节点及其父节点,因为可能会合并两个{{}}节点。因此,还有其他链接程序会增加加载时间。当然,对于少数这种情况,差异并不重要,但是在大量项目的中继器中使用它时,会在运行时环境较慢的情况下产生影响。


2

在此处输入图片说明

Ng-Bind之所以更好的原因是,

当您的页面未加载或互联网速度缓慢或网站加载了一半时,您会看到这些类型的问题(检查带有已读标记的屏幕快照)将在完全奇怪的屏幕上触发。为了避免这种情况,我们应该使用Ng-bind


1

ng-bind也有问题。当您尝试使用角度滤镜限制或其他功能时,如果您使用ng-bind可能会遇到问题。但是在其他情况下,ng-bindUX方面更好。当用户打开页面时,他/她将看到(10ms-100ms)打印符号({{...}}),这就是ng-bind更好的原因。


1

{{}}中存在一些闪烁的问题,例如刷新页面时会看到一小段时间的垃圾邮件,因此我们应该使用ng-bind而不是表达式进行数据描述。


0

ng-bind也更安全,因为它表示html为字符串。

因此,例如,'<script on*=maliciousCode()></script>'将显示为字符串而不执行。


0

根据Angular Doc:
由于ngBind是元素属性,因此在页面加载时,绑定使用户不可见...这是主要区别...

基本上,直到每个DOM不装的元素,我们看不到他们,因为ngBind是元素属性,它会等待直到延迟性肌肉酸痛发挥作用... 下面更多信息

ngBind
-指令在模块纳克

ngBind属性告诉AngularJS替换与给定表达式的值指定的HTML元素的文本内容,并更新文本内容时的表达的改变的值。

通常,您不直接使用ngBind,而是使用类似{{expression}}的双重卷曲标记,它类似但较不冗长。

如果模板在AngularJS编译之前由浏览器暂时以其原始状态显示,则最好使用ngBind代替{{expression}}。由于ngBind是元素属性,因此它使页面加载时用户看不到绑定。

解决此问题的另一种方法是使用ngCloak指令。拜访这里

有关ngbind的更多信息,请访问以下页面:https : //docs.angularjs.org/api/ng/directive/ngBind

您可以将ng-bind作为属性来执行以下操作:

<div ng-bind="my.name"></div>

或如下进行插值:

<div>{{my.name}}</div>

或者用AngularJs中的ng-cloak属性的这种方式:

<div id="my-name" ng-cloak>{{my.name}}</div>

ng-cloak避免在dom上闪烁并等待所有准备就绪!这等于ng-bind属性...


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.