浅谈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 相关文章推荐
javascript判断用户浏览器插件安装情况的代码
Jan 01 Javascript
JS限制上传图片大小不使用控件在本地实现
Dec 19 Javascript
THREE.JS入门教程(4)创建粒子系统
Jan 24 Javascript
JavaScript中的object转换成number或string规则介绍
Dec 31 Javascript
freemarker判断对象是否为空的方法
Aug 13 Javascript
JS中检测数据类型的几种方式及优缺点小结
Dec 12 Javascript
jQuery DateTimePicker 日期和时间插件示例
Jan 22 Javascript
深入浅析vue组件间事件传递
Dec 29 Javascript
详解html-webpack-plugin用法全解
Jan 22 Javascript
Nuxt.js SSR与权限验证的实现
Nov 21 Javascript
JavaScript惰性求值的一种实现方法示例
Jan 11 Javascript
JS实现字体背景跑马灯
Jan 06 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循环创建目录示例分享(php创建多级目录)
2014/03/04 PHP
php导出csv文件,可导出前导0实例代码
2016/11/16 PHP
PHP实现绘制二叉树图形显示功能详解【包括二叉搜索树、平衡树及红黑树】
2017/11/16 PHP
document.getElementById为空或不是对象的解决方法
2010/01/24 Javascript
JSCode all of Brower 全局屏蔽网页右键功能 具体实现
2013/06/05 Javascript
js图片预加载示例
2014/04/30 Javascript
jQuery 判断图片是否加载完成方法汇总
2015/08/10 Javascript
javascript仿百度输入框提示自动下拉补全
2016/01/07 Javascript
JavaScript计算器网页版实现代码分享
2016/07/15 Javascript
javascript动画之模拟拖拽效果篇
2016/09/26 Javascript
node.js express中app.param的用法详解
2017/07/16 Javascript
jQuery Position方法使用和兼容性
2017/08/23 jQuery
BootStrap Table实现server分页序号连续显示功能(当前页从上一页的结束序号开始)
2017/09/12 Javascript
vue.js todolist实现代码
2017/10/29 Javascript
Vue实现搜索 和新闻列表功能简单范例
2018/03/16 Javascript
微信小程序中进行地图导航功能的实现方法
2018/06/29 Javascript
初学node.js中实现删除用户路由
2019/05/27 Javascript
微信小程序基于movable-view实现滑动删除效果
2020/01/08 Javascript
Python编写登陆接口的方法
2017/07/10 Python
Python使用paramiko操作linux的方法讲解
2019/02/25 Python
python tkinter实现界面切换的示例代码
2019/06/14 Python
django一对多模型以及如何在前端实现详解
2019/07/24 Python
基于pytorch padding=SAME的解决方式
2020/02/18 Python
Python matplotlib修改默认字体的操作
2020/03/05 Python
欧洲最大的化妆品连锁公司:Douglas道格拉斯
2017/05/06 全球购物
node中使用shell脚本的方法步骤
2021/03/23 Javascript
什么是岗位职责
2013/11/12 职场文书
网上卖盒饭创业计划书范文
2014/02/07 职场文书
餐厅采购员岗位职责
2014/03/06 职场文书
教师党员学习群众路线心得体会
2014/11/04 职场文书
2014会计年终工作总结
2014/12/20 职场文书
幼儿园卫生保健制度
2015/08/05 职场文书
聘任书范文大全
2015/09/21 职场文书
表扬稿表扬信的格式及范文
2019/06/24 职场文书
Python基础详解之描述符
2021/04/28 Python
FP-growth算法发现频繁项集——构建FP树
2021/06/24 Python