Angular 1.3 one-time binding引见

Angular 1.3 版本终究放出,在更新了很多新特征的同时也修复了很多bug而且带来机能提拔。为了协助本身也协助他人更早明白这些新特征,接下来将会有一个系列文章去引见这些主要的新特征和革新。本片文章是这个系列的第一篇,将引见这个中最主要的一个新特征:one-time bindng。

唉,先别急!我记得Angular的数据绑定是自动坚持UI同步更新的啊?没错,这个特性非常主要,但不肯定一切处所都须要。这类数据绑定的体式格局须要框架时刻看管着一切绑定过的数据,这类体式格局真的很斲丧机能。one-time binding 恰是为处置惩罚此题目而生的。在引见 one-time binding 之前,先明白一下数据绑定和watcher的的观点。

明白数据绑定和watchers

为了完成数据绑定,Angular 运用了 $watch API去视察 scope 上的数据的修改。个中 scope 详细是什么怎样构成的取决于你的代码。假如你没有手动建立一个 child scope ,比方经由历程 ngController 指令去建立,那末你多是在和 $rootScope 打交道,这个 $rootScope 是指当前运用的平常经由历程 ngApp 指令建立的根 scope。

和 scope 打交道并视察个中的变化平常老是要用到所谓的 watcher 。Watchers 经由历程 DOM 中的 directives 注册。比方说经由历程直接 interpolation 指令去同步 scope 模子的值:

<p>Hello {{name}}!</p>

这个 interpolation 指令注册了一个用于 $rootScope 上 name 属性的 watcher,从而能够更新绑定了这个属性值的DOM。

我们能够在 socpe 上经由历程标识符直接定义一个属性并同时给它赋值,如许它就能够直接在DOM中显现:

angular.module('maApp', [])
.run(function($rootScope) {
  $rootScope.name = 'Pascal';
});

我们方才经由历程 interpolation 指令在 view 上绑定了一了一个 model 值,假如转变它的值,view 也会同时自动更新。能够经由历程增加一个按钮完成更新 name 属性值的操纵:

<button ng-click="name = 'Christoph'">Click me!</button>

点击这个按钮会把 Christoph 赋给 name 属性,这触发了一个 $digest 能够坚持 DOM 响应更新的轮询。在这个例子中数据的更新只是单向的(上->下)。假如是在用到 ngModel 的 input 元素的例子中,用户能够输入内容转变这个属性的值,同时转变也及时的返回到现实的 model 上。

这些是因为一个 $digest 轮询被触发才发作的,Angular 负责处置惩罚一切当前 scope 和它的 child scope 上注册过的 watchers,并搜检 model 是不是经由修改,然后直到 model 稳固挪用而且没有更多的 listeners 被点燃,对应的 listeners 被挪用。
以下是以上形貌的代码结果展现:
plnkr

太多watcher的题目

如今我们已对 Angular 中的数据绑定机制有了一个大抵的相识,那末能够想到为何会须要 one-time binding 如许的特征呢?

鉴于运用 watcher 来完成数据绑定的实质,我们能够会碰到有太多 watcher 时较差机能的题目。正如我们所相识的那样,watch expressions 和他们对应的 callback listeners 都是是注册在 scope 上的,基于此 Angular 能够在 $digest 轮询的时刻处置惩罚它们也就坚持了响应的 view 更行。简朴地说,越多 watchers 被注册,Angular 要处置惩罚的也就越多。

如今设想一种有很多动态值在 view 中的场景。比方国际化历程黑白经常见的一种状况,须要 Angular 的数据绑定去做运用的本地化,只管言语只在初始设置页才会变动,而在运行时是不会转变的。此情形下每个字符串都被本地化到 view 中,同时也被写入到 scope 里,而且注册一个对应的 watcher 用于下次 $digest 轮询时能够的更新。假如言语确实不太能够在运行时转变,如许的价值实在是太高了。

one-time binding 来挽救你们了!

终究到了主角上台的时刻了。那末什么是 one-time bindings ?文档里是这么说的:

One-time expressions will stop recalculating once they are stable, which happens after the first digest…
第一次 digest 后,One-time 表达式一旦稳固后就不会再更新。

上面提到的场景确实是 Angular 应该处置惩罚的题目。Angular 1.3 中引入了一种新语法用于示意 interpolation 指令绑定的 one-time。只须要在表达式前到场 :: 双引号即可。一样是上面的例子,我们只须要把:

<p>Hello {{name}}!</p>

改成:

<p>Hello {{::name}}!</p>

这一样适用于其他 Angular 中典范的表达式。比方在 ng-repeat 表达式中或许仅须要从内部暴露出一个属性值的指令(不会从外部转变),只须要在外部把它设置为 one-time 表达式:

<custom-directive two-way-attribute="::oneWayExpression"></custom-directive>

下面是现实例子中的结果,已把上面例子中的 name 改成了 ::name示意 one-time binding,其他则代码完整一样。注重按钮的作用是把 name 更新为 Christoph,不过再试试看:
plnkr
name不会再发作转变!

原文链接

    原文作者:2hu10n92hen9
    原文地址: https://segmentfault.com/a/1190000000740095
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞