AngularJS:为什么ng-bind在角度上优于{{}}?

Nai*_*air 401 javascript angularjs ng-bind

我在其中一个有角度的演示文稿中,提到的会议中的一个人ng-bind{{}}绑定更好.

其中一个原因是,ng-bind将变量放在监视列表中,并且只有在模型更改时才{{}}会将数据推送到视图,另一方面,每次都会插入表达式(我猜这是角度循环)并推动值,即使值发生变化.

另外据说,如果您在屏幕上没有太多数据可以使用{{}},并且性能问题将不可见.有人可以为我解释这个问题吗?

Kon*_*ass 543

能见度:

虽然您的angularjs是自举的,但用户可能会在html中看到您放置的括号.这可以用来处理ng-cloak.但对我来说,这是一种解决方法,如果我使用,我不需要使用ng-bind.


性能:

{{}}慢得多.

ng-bind是一个指令,将把一个观察者放在传递的变量上.因此,ng-bind只有当传递的值确实发生变化时,才会适用.

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


我目前正在构建一个大的单页应用程序(每个视图约500个绑定).从{{}}更改为严格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>
Run Code Online (Sandbox Code Playgroud)

例:

ng-repeat输出表中的一些数据,每行有多个绑定.翻译绑定,过滤输出,在每个范围摘要中执行.

  • 这是一个更好的答案 (32认同)
  • 从我从源头上可以看出(截至2014-11-24),卷曲插值的处理就像一个指令(参见ng/compile.js中的addTextInterpolateDirective()).它还使用$ watch,因此如果文本没有改变则不会触及DOM,它不会在您声明的每个$ digest上"脏检查并刷新"它.但是,对每个$摘要所做的是计算插值结果字符串.除非它发生变化,否则它不会分配给文本节点. (13认同)
  • 我为内部评估写了一个性能测试.它在ng重复中有2000个条目,并在对象中显示2个属性,因此2000x2绑定.绑定的不同之处在于:第一个绑定只是跨度中的绑定.秒有一个绑定和一些简单的HTML.结果:每个范围适用的ng-bind速度提高了约20%.在没有检查代码的情况下,似乎在html元素中使用卷曲表达式的额外普通html需要更多时间. (6认同)
  • 只是想指出根据这里的测试:http://jsperf.com/angular-bind-vs-brackets似乎表明括号比绑定更快.(注意:条形图是每秒操作数,因此越长越好).正如先前的评论所指出的那样,他们的观察机制最终是相同的. (2认同)

hol*_*ple 322

如果您不使用ng-bind,请改为:

<div>
  Hello, {{user.name}}
</div>
Run Code Online (Sandbox Code Playgroud)

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

你可以这样做

<div>
  Hello, <span ng-bind="user.name"></span>
</div>
Run Code Online (Sandbox Code Playgroud)

如果这对你来说是一个问题.

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

  • 对我来说,这不是问题的答案,为什么ngBind更好.这是如何使用ngBind而不是{{}}注释和对ngCloak的引用. (17认同)
  • @KevinMeredith看起来像HTML加载时,但角度还没有(还).请记住,这是我们正在讨论的客户端模板.所有插值都必须在加载应用程序的浏览器中完成.通常角度载荷足够快,以至于不会引起注意,但在某些情况下它会成为一个问题.因此,发明了`ng-cloak`来解决这个问题. (5认同)
  • 如果我不想在span标签中包装user.name,如何使用ng-bind?如果我使用大括号,我会得到干净的名字,没有html标签 (4认同)
  • @Victor还有`ng-bind-template`,你可以在这两种方法中结合使用:`ng-bind-template ="Hello,{{user.name}}"`这里绑定仍然提供了性能提升,并没有引入任何进一步的嵌套 (4认同)
  • 根据你所说的,如果我们使用{{}},就不会有性能影响?有人告诉我,如果你每次使用{{}},即使模型没有改变,也会得到inerpolate并产生结果. (3认同)
  • 在这里游戏的后期超级,但问题是关于ngBind指令的性能优势,这个答案没有解决. (2认同)

小智 29

ng-bind 比...更好 {{...}}

例如,您可以这样做:

<div>
  Hello, {{variable}}
</div>
Run Code Online (Sandbox Code Playgroud)

这意味着,整个文本Hello, {{variable}}由封闭<div>将被复制,并存储在内存中.

如果你做了这样的事情:

<div>
  Hello, <span ng-bind="variable"></span>
</div>
Run Code Online (Sandbox Code Playgroud)

只有值的值将存储在内存中,而angular将注册一个仅由变量组成的观察者(监视表达式).

  • 另一方面,您的DOM更深入.根据您正在做的事情,在大文档中,这可能会影响渲染性能. (7认同)
  • `<div ng-bind-template ="{{var1}},{{var2}}"> </ div>`是{{}}的替代品,其功能类似于ng-bind (3认同)
  • 是的,我认为@stephband也是这样.例如,如果您只想显示姓名和姓氏.为什么不插入?它将以相同的方式执行,因为它将在1个摘要中运行相同的手表.例如:<div> {{firstName}} {{lastName}} </ div> == <div> <span ng-bind ="firstName"> </ span> <span ng-bind ="lastName"> </ span> </ div> ..第一个看起来更好.我认为这很大程度上取决于你想要什么,但最终它们都有优点和缺点. (2认同)

小智 15

基本上,双卷曲语法更自然可读,并且需要更少的输入.

这两种情况都会产生相同的输出但是..如果您选择使用{{}},则有可能用户{{}}在模板呈现角度之前会看到几毫秒.所以,如果你注意到任何东西,{{}}那么最好使用ng-bind.

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

  • 有趣的是,它不一样.我在ng-bind ="anArrayViaFactory"vs {{anArrayViaFactory}}上没有输出.我在尝试以jekyll原型输出json响应时遇到了这个问题但由于与类似模板{{}}的冲突,我被迫使用ng-bind.ng-repeat块内的ng-bind(anArrayViaFactory中的项)将输出值. (5认同)

Tes*_*mas 5

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

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

<div>
  Hello, <span ng-bind="variable"></span>
</div>
Run Code Online (Sandbox Code Playgroud)