浅谈angular.js中实现双向绑定的方法$watch $digest $apply


Posted in Javascript onOctober 14, 2015

Angular.js 中的特性,双向绑定.

多么神奇的功能,让视图的改变直接反应到数据中,数据的改变又实时的通知到视图,如何做到的?

这要归功于 scope 下面3个重要的方法:

$watch
$digest
$apply

他们的区别是什么,我们来介绍下:

$watch
这是一个监听 scope 上数据的监听器

方法说明:

$scope.$watch('参数',function(newValue,oldValue){
 //逻辑处理
})

上面我们就是创建了一个监听器.
‘参数' 就是$scope对象下的一个对象(或者一个对象的属性),注意,这里是字符串形式.

假如你要监听 $scope.name 属性.

$scope.$watch('name',function(newValue,oldValue){
 //逻辑处理
})

如上代码, ‘name' 需要引号

参数后面跟着回调函数,回调函数参数返回了被监听 属性,变化后的新值,以前变化前的旧值.

$digest

他负责检查 scope 中的数据是否发生了变化,如果某个属性有变化,马上会通知此属性的监听器 ($watch 注册的监听器),触发监听器,执行回调函数.

$apply

这个方法和 $digest 很相似, $digest 检查scope 中的所有数据
$apply 相当于检查 rootScope 中的所有数据,他会从父级到子级来检查所有数据

$apply() == $rootScope.$digest()

$apply() 方法有两种形式.

第一种 接受一个 function作为参数.
这样触发 $digest 函数并且执行一次 参数中的 function

第二种  不接受任何参数.
这样只是触发一轮 $digest 父级到子级的循环

Angular.js 中一班不会直接调用 $digest ,而是用 $scope.$apply() 来代替

我没有设定监视器,为什么视图和数据可以双向绑定

比如一个文本框 ng-model="name"
这时其实 $scope 对象下已经有了一个属性 name 来对应和 上面的视图进行双向绑定

如何实现的?

其实,当我们定义 ng-model="name"  或者 ng-bind="name" 或者 {{name}}
这时 angular.js 会在 $scope 模型上自动为 “name” 属性设置一个监听器:

$scope.$watch('name', function(newValue, oldValue) {
  //监听 name 属性的变化
});

原来这里 angular.js 帮我们自动创建了一个监听器,所以此属性和 $scope.name 数据才会实时的双向绑定.

当然,有时候你也会发现明明数据变化了.但是UI 没有刷新,是双向绑定失效了吗?

没有

只是在 $scope 模型遍历 digest 循环时,你的数据还没有返回来,

比如异步调用方法,callbac 返回的数据
比如你在 setTimeout 设置了定时触发函数,然后修改模型数据
总之,是错过了 $scope 模型的 digest 循环,导致模型没有通知UI去根据新数据刷新.

遇到这样的问题怎么办?

我们只好自己去手动调用 digest来循环检查一次数据.实现双向绑定

上面我们已经说过,通常不要去直接调用 digest 方法,而是手动调用 $apply 方法,间接实现触发 $digest 循环.

如下:

setTimeout(function() {
 $scope.name= '一介布衣';
 $scope.$apply();
}, 2000);

问题来了,上面时候该去手动调用 apply 方法

目前为止, angular.js 为一部分指令和服务自动实现了 $apply() 方法.

例如, ng-click ,ng-model ,$timeout服务,$http服务 等

调用后,angular.js 会自动帮我们调用 $apply() 来实现数据双向绑定.

Javascript 相关文章推荐
禁止JQuery中的load方法装载IE缓存中文件的方法
Sep 11 Javascript
jQuery timers计时器简单应用说明
Oct 28 Javascript
基于jQuery的弹出框插件
Mar 18 Javascript
javaScript函数中执行C#代码中的函数方法总结
Aug 07 Javascript
js密码强度检测
Jan 07 Javascript
JS实现兼容火狐及IE iframe onload属性的遮罩层隐藏及显示效果
Aug 23 Javascript
Angular ng-repeat 对象和数组遍历实例
Sep 14 Javascript
chrome下判断点击input上标签还是其余标签的实现方法
Sep 18 Javascript
Vue组件开发初探
Feb 14 Javascript
jQuery 1.9版本以上的浏览器判断方法代码分享
Aug 28 jQuery
解决Vue2.0中使用less给元素添加背景图片出现的问题
Sep 03 Javascript
JS实现利用闭包判断Dom元素和滚动条的方向示例
Aug 26 Javascript
JS更改select内option属性的方法
Oct 14 #Javascript
JavaScript+CSS实现仿Mootools竖排弹性动画菜单效果
Oct 14 #Javascript
JS实现的最简Table选项卡效果
Oct 14 #Javascript
JS仿淘宝实现的简单滑动门效果代码
Oct 14 #Javascript
JavaScript实现的伸展收缩型菜单代码
Oct 14 #Javascript
smartcrop.js智能图片裁剪库
Oct 14 #Javascript
深入学习JavaScript对象
Oct 13 #Javascript
You might like
php判断字符以及字符串的包含方法属性
2008/08/30 PHP
PHP如何解决网站大流量与高并发的问题
2011/06/25 PHP
PHP 生成N个不重复的随机数
2015/01/21 PHP
php从给定url获取文件扩展名的方法
2015/03/14 PHP
ajax不执行success回调而是执行了error回调
2012/12/10 Javascript
谈谈JavaScript中的函数与闭包
2013/04/14 Javascript
jquery自定义类似$.ajax()的方法实现代码
2013/08/13 Javascript
javascript中负数算术右移、逻辑右移的奥秘探索
2013/10/17 Javascript
jQuery实现的指纹扫描效果实例(附演示与demo源码下载)
2016/01/26 Javascript
微信小程序实现简单input正则表达式验证功能示例
2017/11/30 Javascript
30分钟快速入门掌握ES6/ES2015的核心内容(上)
2018/04/18 Javascript
VeeValidate 的使用场景以及配置详解
2019/01/11 Javascript
微信小程序云开发实现增删改查功能
2019/05/17 Javascript
详解基于Wepy开发小程序插件(推荐)
2019/08/01 Javascript
解决vue自定义全局消息框组件问题
2019/11/22 Javascript
微信小程序以7天为周期连续签到7天功能效果的示例代码
2020/08/20 Javascript
Python中的数据对象持久化存储模块pickle的使用示例
2016/03/03 Python
整理Python 常用string函数(收藏)
2016/05/30 Python
python flask 多对多表查询功能
2017/06/25 Python
python机器学习理论与实战(六)支持向量机
2018/01/19 Python
python中的turtle库函数简单使用教程
2018/07/23 Python
Python Flask框架扩展操作示例
2019/05/03 Python
从列表或字典创建Pandas的DataFrame对象的方法
2019/07/06 Python
python学生管理系统的实现
2020/04/05 Python
Python文件时间操作步骤代码详解
2020/04/13 Python
PyCharm2020.3.2安装超详细教程
2021/02/08 Python
加拿大最大的体育用品、鞋类和服装零售商:Sport Chek
2018/11/29 全球购物
internal修饰符起什么作用
2013/12/16 面试题
大学新生军训个人的自我评价
2013/10/03 职场文书
2014年人事专员工作总结
2014/11/19 职场文书
2014年财政工作总结
2014/12/10 职场文书
公司介绍信范文
2015/01/31 职场文书
干部考核工作总结2015
2015/07/24 职场文书
电力培训学习心得体会
2016/01/11 职场文书
java基础——多线程
2021/07/03 Java/Android
基于PostgreSQL/openGauss 的分布式数据库解决方案
2021/12/06 PostgreSQL