深入浅析AngularJS中的一次性数据绑定 (bindonce)
一、理解双向数据绑定和监听器
为了实现双向数据绑定,AngularJS使用了$watch
API来观察期作用域中的模型变化。具体的作用域取决于你的代码如何编写。如果你没有创建一个自作用域,就是说没有使用ngController指令在你的DOM和你的控制器代码之间创建一个关联,你可能处理的是跟作用域$rootScope
,这个作用域由ngApp自动创建,并且是应用中所有作用域的父作用域,当然,如果你选择手动启动AngularJS,那情况就另当别论了。每当你创建了一个数据绑定时,AngularJS就会自动创建一个监听器来监听这个数据的变化。比如说下面这个简单的例子:
<p>Hello {{name}}!</p>
在这个例子中,我们使用了插值指令,这个指令会注册一个监听器来监听相应作用域中属性name的变化,并在该属性发生变化时将它实时反应到DOM中。
添加下面的代码,你的name属性将会自动的被赋值为Pascal:
angular.module('myApp', []) .run(function ($rootScope) { $rootScope.name = "Pascal"; }]);
通过上面的代码,我们就成功的使用了插值指令创建了在试图上创建了一个数据绑定。现在,如果name属性发生变化,视图将会自动发生更新。比如说我们添加下面的代码,在按钮点击是修改name的值:
<button ng-click="name = 'Christoph'">Click me!</button>
此时,点击按钮,我们可以将name的值修改为Christoph,同时我们会触发一个$digest循环来更新DOM中相应的部分。在上面的例子中,你看的知识单向数据绑定。然而,你完全可以使用ngModel指令来将视图中发生的变化实时的反应到模型中。
上面的双向绑定魔法的实现完全依赖于$digest
循环,当$digest循环被触发时,AngularJS将会去处理遍历当前作用域和子作用域中的所有监听器,然后通过检查模型中发生的变化来更新DOM中的值,直到模型不再发生变化为止。一旦$digest循环执行完成,浏览器会重新渲染DOM来反应模型数据变化。
现在,我们大概了解了AngularJS的数据绑定机制,你可能会问我们为何还需要一次性数据绑定。
由于AngularJS使用监听器来实现数据绑定。当监听器越来越多时,可能会出现一些性能上的问题。由于在注册监听器使,同时会注册一个回调函数,以便在$digest循环执行时能够相应的更新视图。也就是说,监听器越多,AngularJS需要处理的回调函数也就越多。
现在假设在视图中有很多值需要被AngularJS处理。比如说像上面使用插值指令来进行数据绑定,虽然我们可能并不想让这个值只绑定一次,比如说上面的Pascal,在应用代码执行的整个过程中这个属性都不会发生改变,但是AngularJS默认依然会在这个属性上绑定一个监听器和回调函数。因此,在$digest
时,AngularJS依然会去特意的关注这个值,这实在是有些过头了。
二、一次性数据绑定(One-time bindings)
这就是我们需要一次性数据绑定的原因。在AngularJS的文档中,我们可以清楚的了解到这个新特性的作用:一次性数据绑定表达式可以在数据稳定之后,不需要在$digest
循环中重计算…
一次性数据绑定的出现解决了前面提到的由监听器太多带来的性能问题。那么我们应该如何使用一次性数据绑定呢?
使用一次性数据绑定非常的简单,我们只需要在表达式之前加上双冒号::即可。比如,前面我们使用了插值指令将name属性绑定到了视图中:
<p>Hello {{name}}!</p>
使用一次性数据绑定,我们这样写:
<p>Hello {{::name}}!</p>
在AngularJS 1.3版本中,你可以在任何AngularJS的表达式中使用一次性数据绑定。即使在诸如ng-repeat这样严重依赖于双向绑定的指令中,你依然可以使用它。
以上所述是小编给大家介绍的AngularJS中的一次性数据绑定 (bindonce),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
- Gitlab利用Webhook实现Push代码后的jenkins自动构建
- db4o 7.4 for .net3.5试用手记
- JQuery笔记(五) 圆角表格的效果
- tomcat内存溢出问题记录
- 微信小程序开放 Wi-Fi、NFC 连接能力,未来可直接刷地铁?
- 2017奇葩机器人大盘点:Sophia想生孩子,Atlas后空翻,贝佐斯骑高达
- silverlight:分享一个不错的自定义布局CollectionFlow(可用于制作相册的哦!)
- 无法取得ConnectionSettings的问题
- DataTable,List去重复记录的方法
- Uploadify的一点总结
- 自动驾驶时代,中国移动要以怎样的姿势进入?
- JQuery中文日期控件
- Silverlight中的帧
- 窗口自动弹出浏览器显示广告的问题
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Pytorch 卷积中的 Input Shape用法
- 解决TensorFlow程序无限制占用GPU的方法
- 基于Python的自媒体小助手—登录页面的实现代码
- PHP addAttribute()函数讲解
- PHP PDOStatement::setAttribute讲解
- PHP中的访问修饰符简单比较
- PHP asXML()函数讲解
- PhpStorm配置Xdebug调试的方法步骤
- python字典的值可以修改吗
- 使用Keras构造简单的CNN网络实例
- Python接口测试环境搭建过程详解
- 使用已经得到的keras模型识别自己手写的数字方式
- 解决keras使用cov1D函数的输入问题
- PHP PDOStatement::getColumnMeta讲解
- PHP PDOStatement::nextRowset讲解