AngularJS 的数据绑定
单向绑定(ng-bind) 和 双向绑定(ng-model) 的区别
ng-bind
单向数据绑定($scope -> view
),用于数据显示,简写形式是 {{}}
。
1 |
<span ng-bind="val"></span> |
两者的区别在于页面没有加载完毕 {{val}}
会直接显示到页面,直到 Angular 渲染该绑定数据(这种行为有可能将 {{val}}
让用户看到);而 ng-bind
则是在 Angular 渲染完毕后将数据显示。
ng-model
是双向数据绑定($scope -> view
and view -> $scope
),用于绑定值会变化的表单元素等。
1 |
<input type="text" ng-model="val" /> |
双向数据绑定的原理
双向数据绑定意味着当 view
中有任何数据发生变化会自动地反馈到 scope
的数据上,当 scope
模型发生变化时,view
中的数据也会更新到最新的值。很显然,这需要一个监控。
事实上,AngularJS 确实在幕后为 scope
模型上设置了一个 监听队列,用来监听数据变化并更新view
。
每次绑定一个东西到 view
上时 AngularJS 就会往 $watch
队列里插入一条 $watch
,用来检测它监视的 model
里是否有变化的东西。
当浏览器接收到可以被 angular context
处理的事件时,$digest
循环就会触发。$digest
会遍历所有的 $watch
。
一次更新的操作(至少触发两次 $digest() 循环)
比如进行一次 click
操作:
1 |
<button ng-click="val=val+1">increase 1</button> |
- 按下按钮
- 浏览器接收到一个事件,进入
angular context
$digest
循环开始执行,查询每个$watch
是否变化- 由于监视
$scope.val
的$watch
报告了变化,它会强制再执行一次$digest
循环。 - 新的
$digest
循环没有检测到变化。 - 浏览器拿回控制权,更新与
$scope.val
新值相应部分的DOM
。
$digest 循环会运行多少次?
$digest
循环不会只运行一次。在当前的一次循环结束后,它会再执行一次循环用来检查是否有models
发生了变化。
这就是脏检查(Dirty Checking
),它用来处理在 listener
函数被执行时可能引起的 model
变化。因此 $digest
循环会持续运行直到 model
不再发生变化,或者 $digest
循环的次数达到了 10
次(超过 10
次后抛出一个异常,防止无限循环)。
当 $digest
循环结束时,DOM
相应地变化。
$apply() 和 $digest() 的区别
$apply
是 $scope
(或者是 direcvie
里的 link
函数中的 scope
)的一个函数,调用它会强制一次 $digest
循环(除非当前正在执行循环,这种情况下会抛出一个异常,这是我们不需要在那里执行 $apply
的标志)。
$apply()
和 $digest()
有两个区别。
1) 最直接的差异是, $apply
可以带参数,它可以接受一个函数,然后在应用数据之后,调用这个函数。所以,一般在集成非 Angular 框架(比如jQuery)的代码时,可以把代码写在这个里面调用。
2) 当调用 $digest
的时候,只触发当前作用域和它的子作用域上的监控,但是当调用 $apply
的时候,会触发作用域树上的所有监控。
什么时候手动调用 $apply() 方法?
取决于是否在 Angular 上下文环境(angular context
)。
典型的需要调用 $apply()
方法的场景是:
1) 使用了 JavaScript 中的 setTimeout()
来更新一个 scope model
2) 用指令设置一个 DOM
事件 listener
并且在该 listener
中修改了一些 models
场景一
1 |
$scope.setMsg = function() { |
运行这个例子,会看到过了两秒钟之后,控制台确实会显示出已经更新的 model
,然而,view
并没有更新。
在 $scope.getMessage
加入 $apply()
方法。
1 |
$scope.getMessage = function() { |
再运行就 OK 了。
不过,在 AngularJS 中应该尽量使用 $timeout
Service 来代替 setTimeout()
,因为前者会帮你调用 $apply()
,让你不需要手动地调用它。
1 |
$timeout(function(){ |
场景二
实现一个 click
的指令,类似以下功能:
1 |
<button ng-click="val=val+1">increase 1</button> |
directive
的编写如下:
1 |
app.directive("inc", function() { |
跟场景一的结果一样,这个时候,点击按钮,界面上的数字并不会增加。但查看调试器,发现数据确实已经增加了。
在 scope.val++;
一行后面添加 scope.$apply();
或者 scope.$digest();
就 OK 了。
$apply() 方法的两种形式
1) 无参
1 |
$scope.$apply() |
2) 有参
1 |
$scope.$apply(function(){ |
应该总使用接受一个 function
作为参数的 $apply()
方法。这是因为当传入一个 function
到$apply()
中的时候,这个 function
会被包装到一个 try…catch
块中,所以一旦有异常发生,该异常会被 $exceptionHandler service
处理。
想象一下如果有个 alert
框显示错误给用户,然后有个第三方的库进行一个网络调用然后失败了,如果不把它封装进 $apply
里面,Angular 永远不会知道失败了,alert
框就永远不会弹出来了。
在 AngularJS 中使用 $watch
常用的使用方式:
1 |
$scope.name = 'htf'; |
传入到 $watch()
中的第二个参数是一个回调函数,该函数在 name
的值发生变化的时候会被调用。
如果要监听的是一个对象,那还需要第三个参数:
1 |
$scope.data.name = 'htf'; |
表示比较的是对象的值而不是引用,如果不加第三个参数 true
,在 data.name
变化时,不会触发相应操作,因为引用的是同一引用。
参考
- 理解$watch ,$apply 和 $digest —- 理解数据绑定过程
- 理解Angular中的$apply()以及$digest()
- Angular沉思录(一)数据绑定
- 构建自己的AngularJS,第一部分:Scope和Digest
转:http://huangtengfei.com/2015/09/data-bind-of-angularjs/
AngularJS 的数据绑定的更多相关文章
- 10分钟学会AngularJS的数据绑定
前言:为什么要用AngularJS? 相信用过.NetMVC的人都知道用rezor绑定数据是一件很爽的事情,C#代码直接在前台页面中输出.然后这种比较适用于同步请求. 当我们的项目离不开异步请 ...
- AngularJS双向数据绑定
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 02、AngularJs的数据绑定
我们知道,AngularJs中的数据绑定是双向绑定的,View的改变,会改变Model,Model的改变也会改变View中的值,废话不多说,我们直接上代码. <!DOCTYPE html> ...
- AngularJS笔记---数据绑定
一.数据绑定 1.简单绑定 下面实现了一个简单的加法运算的绑定, A.ng-app:表示该div以内都在AngularJS的应用, 去掉ng-app="" 那么后面的绑定都将无效 ...
- Vue、AngularJS 双向数据绑定解剖
数据与视图的绑定与同步,最终体现在对数据的读写处理过程中,也就是 Object.defineProperty() 定义的数据 set.get 函数中.Vue 中对于的函数为 defineReactiv ...
- 关于 AngularJS 的数据绑定
单向绑定(ng-bind) 和 双向绑定(ng-model) 的区别 ng-bind 单向数据绑定($scope -> view),用于数据显示,简写形式是 {{}}. 1 <span n ...
- 关于AngularJs,数据绑定与自定义验证
最近开始着手学起了Angular,抱着好奇的心情开始研究了起来.忽然发现angular可以巧妙而方便的进行数据的绑定验证啊什么的.(当然,我只是刚开始学,所有可能有更强大的功能,只是我还没有看到) 那 ...
- AngularJS入门心得2——何为双向数据绑定
前言:谁说Test工作比较轻松,最近在熟悉几个case,差点没疯.最近又是断断续续的看我的AngularJS,总觉得自己还是没有入门,可能是自己欠前端的东西太多了,看不了几行代码就有几个常用函数不熟悉 ...
- AngularJS语法基础及数据绑定——详解各种数据绑定指令、属性应用
AngularJS简单易学,但是功能强大.特别是在构建单页面应用方面效果显著.而 数据绑定 可以说是他被广泛使用的最主要的优点.他舍弃了对DOM的操作方式,一切都由AngularJS来自动更新视图,我 ...
随机推荐
- GridControl控件绑定RepositoryItemImageComboBox 作为下拉框使用
如果,时间长时了,已前做过的东西,都记不得了,所以记录一下. 废话不多说. 1.拖出gridview控件,然后将字段绑定上去 2.将要做下拉框的控件加入RepositoryItemImageCombo ...
- 【转】【C#】C#重绘windows窗体标题栏和边框
摘要 windows桌面应用程序都有标准的标题栏和边框,大部分程序也默认使用这些样式,一些对视觉效果要求较高的程序,如QQ, MSN,迅雷等聊天工具的样式则与传统的windows程序大不相同,其中迅雷 ...
- 给 IIS Express 配置虚拟目录
使用 vs2015 打开旧项目,之前使用 iis 配置站点,然后在 vs 中附加 w3wp.exe 进行开发和调试的. 由于种种原因 iis 上配置站点各种失败. 之后发现,其实在 vs2015 中按 ...
- scala学习之第二天:可变容器与不可变容器的特性与应用
1.具体的不可变集合实体类 List(列表) 是一种有限的不可变序列式.提供了常数时间的访问列表头元素和列表尾的操作,并且提供了常数时间的构造新链表的操作,该操作将一个新的元素插入到列表的头部.其他许 ...
- m3u8字段意义解析
m3u8字段意义解析 HLS,Http Live Streaming是由Apple公司定义的用于实时流传输的协议,HLS基于HTTP协议实现,传输内容包括两部分,一是M3U8描述文件,二是TS媒体文件 ...
- ffmpeg常用基本命令(转)
[FFmpeg]FFmpeg常用基本命令 1.分离视频音频流 ffmpeg -i input_file -vcodec copy -an output_file_video //分离视频流 ffmpe ...
- Enfold主题详解与实例视频教程 WordPress建站视频教程
ENFOLD主题功能强大,同样的设置也相对较复杂,希望您在学习过程中也能多多加以练习.Enfold主题介绍:目前在ThemeForest网站,Enfold在WordPress主题销售排行中第2名,可见 ...
- [CareerCup] 9.9 Eight Queens 八皇后问题
9.9 Write an algorithm to print all ways of arranging eight queens on an 8x8 chess board so that non ...
- 20145233韩昊辰 《Java程序设计》实验报告一:Java开发环境的熟悉(Windows+IDEA)
20145233 <Java程序设计>实验报告一:Java开发环境的熟悉 实验要求 使用JDK编译.运行简单的Java程序: 使用IDEA 编辑.编译.运行.调试Java程序. 实验内容 ...
- 详解.NET IL代码
一.前言 IL是什么? Intermediate Language (IL)微软中间语言 C#代码编译过程? C#源代码通过LC转为IL代码,IL主要包含一些元数据和中间语言指令: JIT编译器把IL ...