前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[译]探索Angular 1.3 的单次绑定(one -time bindings)

[译]探索Angular 1.3 的单次绑定(one -time bindings)

作者头像
小刀c
发布2022-08-16 14:56:05
3.1K0
发布2022-08-16 14:56:05
举报
文章被收录于专栏:cc log

toc

译文:英文原文

激动人心的时刻到了,Angular 1.3终于发布了,附带了大量的新功能、bug修复、改进当然也有不足。因为这些新的东西,我们想通过一系列的博文详解主要的功能和改进来让新的版本更快的让大家适应。这是“探索Angular 1.3”系列的第一篇,包含了有史以来最重要的功能:单次绑定(one-time binding)

等等!Angular的数据绑定不是自动和Ui保持同步么?是的,确实是的,这确实很棒。然而,为了实现数据绑定,Angular需要时刻监听相关的值,这就导致了性能问题,而单次绑定就是为此而生。在我们探究单次绑定之前,来让我们先了解了解Angular中数据绑定(databing)和监控器(watcher)的概念。

理解数据绑定和观察者

为了实现数据绑定,Angular使用watch API来监听作用域(scope)中模型(model)的变化。你的应用代码决定了作用域到底是什么到底从哪里。如果你没有创建子作用域,例如通过ngController指令来连接你的DOM和你实际控制器(controller)代码,你就在和rootScope打交道,正如其字面意义,

然而,在你和作用域打交道的同时,一个叫做监控器(watcher)的来监听变化。观察者通过使用在DOM使用指令来注册。让我们使用插入指令来映射DOM作用域中的模型值。

代码语言:javascript
复制
Hello {{name}}!

这个插入指令为作用域(我们的例子里面是$rootScope)所属的name值注册了监控器,以此来将值插入并将其显示到DOM。

在作用域中通过标示符来定义一个属性,并且给他分配值,这样无需进一步的动作,值就会很神奇的现实在DOM。

代码语言:javascript
复制
angular.module('myApp', []) .run(function ($rootScope) { $rootScope.name = "Pascal"; }]);

很好!我们刚才通过一个插入指令将一个模型值和绑定到视图。如果值更改之后,视图就会自动更新。让我们增加一个按钮在被点击时候更新name的值。

代码语言:javascript
复制
<button ng-click="name = 'Christoph'">Click me!</button>;

点击按钮,就会将字符串Christoph赋值给name同时会触发$digest循环,DOM也就是相应自动更新。在特殊的情况下我们只单向(top → down)更新值。然而,譬如input元素有个一个ngModel的指令,随着用户输入,inputvalue属性值随之改变,同时这些变化也会映射到实际的模型。

这能够实现是因为当digest循环触发之后,Angular驱动当前作用域及其子作用域中所有的监控器检查所有的模型变化并调用专门的监听函数直到模型值不再变化并且没有任何监控器被触发。一旦diges循环完成执行。浏览器重新渲染DOM反映这些变化。

下面是例子:

See the Pen EIyAi by yijian166 (@yijian166) on CodePen.

太多监控器所带来的问题

现在知道了Angular中数据绑定的工作机制,我们或许会惊讶为什么还需要单次绑定(one-time binding)这个功能。

因为Angular使用监控器来实现数据绑定的本质,当我们使用太多监控器就会带来性能的问题。正如我们所知,监控表达式以及他们的回调监控函数同时注册在作用域,这样Angular才能在$digest循环的过程中处理他们以此来更新对应的视图。简单来说,注册的监控器越多,Angular需要处理的就越多。

此刻,你想象下在你的视图中有大量的动态值需要被Angular赋值,譬如国际化,这在开发者使用Angular数据绑定来本地化app是一个很常见的场景,甚至当应用的语言在运行不能被改变,只是在初始化的时候设置。在这种场景下视图中的每个字符串都需要被写到作用域中,设置一个监控器以此来一旦下一轮$digest被触发时候能够得到更新。这将会一个很大开支,特别是当你的语言无需再运行时更改。

让单次绑定(one-time binding)来解决这个问题!

这就是单次绑定出现的原因。那么,什么是单次绑定呢?来让我们看看官方文档的说法:

单次表达式(One-time expressions)将会在他们初次稳定也就是在初次digest之后不再被重新计算……

这就解决了我们上面所提到的问题。那么,当我们在使用单次绑定到底是怎么样子的呢?Angular 1.3带来了新的插入指令和表达式以此来告诉Angular这个特殊的插入值应该被只绑定一次。

使用单次绑定我们只需要以::开始表达式即可。因此如果我们需要在上述的例子中使用单次表达式,我们只需改变:

代码语言:javascript
复制
<p>Hello {{name}}</p>

代码语言:javascript
复制
<p>Hello {{::name}}</p>;

这个可以在Angular所有的典型表达式中使用。也就是你可以在ng-repeat中使用,甚至可以由从内而外建立的双向绑定来暴露属性的指令中使用。从外面你可以给他们设置一个单次表达式:

代码语言:javascript
复制
<custom-directive two-way-attribute="::oneWayExpression"></custom-directive>

来让我们看一个实际的例子。我们已经将name更新为了::name来使用单次绑定。下面的代码就证明了可以成功的单次绑定。还记得吧,我们将按钮设置为更新nameChristioph,好,让我们试一试:

代码示例:

See the Pen CDmKr by yijian166 (@yijian166) on CodePen.

完美!`name`并没有再次更改。再说`Pascal`是一个更好的名字对吧?

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • toc
    • 理解数据绑定和观察者
      • 太多监控器所带来的问题
        • 让单次绑定(one-time binding)来解决这个问题!
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档