网站首页 > 基础教程 正文
什么是双向数据绑定
双向数据绑定:
Angular实现了双向绑定机制。所谓的双向绑定,无非是从界面的操作能实时反映到数据,数据的变更能实时展现到界面。即数据模型(Module)和视图(View)之间的双向绑定。
例子:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script> </head> <body> <div ng-app="myApp" ng-controller="myCtrl"> 输入: <input ng-model="name"> <h1>你输入了: {{name}}</h1> </div> <script> var app = angular.module('myApp', []); app.controller('myCtrl', function($scope) { $scope.name = "test"; }); </script> </body> </html>
当你在输入框中进行输入时,也会修改网页中的文本内容。
这里我使用了{{}}来实现了最简单数据绑定,{{}}进行的数据绑定时单向的,只实现了数据展示。然后我用input标签配合ng-model 实现了一个简单的双向数据绑定的例子,双向绑定最常用的场景就是表单,这样当用户在前端页面完成输入后,不用任何操作,我们就已经拿到了用户的数据存放到数据模型中了。
双向数据绑定与单向数据绑定
单向数据绑定:
数据模型–>视图
El表达式中常见 ${变量名}以及{{}} ,它只提供从数据源到视图的单方向的数据展示。
缺点:HTML代码一旦生成完以后,就没有办法再变了,如果有新的数据来了,那就必须把之前的HTML代码去掉,重新整合生成一次。
双向数据绑定:
数据模型<==>视图
用户在视图上的修改会自动同步到数据模型中去,同样的,如果数据模型中的值发生了变化,也会立刻同步到视图中去。
缺点:双向数据绑定的应用场景非常有限。
双向数据绑定原理
带着问题看下面的代码。
问题:绑定数据是怎么生效的?
如图示例,当点击+1按钮时,显示的数据是否会正常的增加?
如果会正常增加,说明原因。
如果不会,说明原因并修改代码使其可以正常显示。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script> </head> <body ng-app="test"> <div ng-controller="CounterCtrl"> <br> <button myclick>+1</button> <br> {{counter}} </div> <script> var app = angular.module("test", []); app.directive("myclick", function() { return function (scope, element, attr) { element.on("click", function() { scope.counter++; }); }; }); app.controller("CounterCtrl", function($scope) { $scope.counter = 0; }); </script> </body> </html>
上一段代码为无法实现页面显示数据增加的功能。
修改方法:
原因从脏检查机制开始说起。
脏检查机制:Angular将双向绑定转换为一堆watch表达式,然后递归这些表达式检查是否发生过变化,如果变了则执行相应的watcher函数(指view上的指令,如ng-bind,ng-show等或是{{}})。等到model中的值不再发生变化,也就不会再有watcher被触发,一个完整的digest循环就完成了。
脏检查机制的触发:Angular中在view上声明的事件指令,如:ng-click、ng-change等,会将浏览器的事件转发给$scope上相应的model的响应函数。等待相应函数改变model,紧接着触发脏检查机制刷新view。
所以,上文中的代码无法实现相应功能的原因就是缺乏触发Angular脏检查机制的条件,而手动添加了scope.$digest()使其执行了脏检查机制更新了view。
watch表达式:可以是一个函数、可以是$scope上的一个属性名,也可以是一个字符串形式的表达式。$watch函数所监听的对象叫做watch表达式。
watcher函数:指在view上的指令(ngBind,ngShow、ngHide等)以及{{}}表达式,他们所注册的函数。每一个watcher对象都包括:监听函数,上次变化的值,获取监听表达式的方法以及监听表达式,最后还包括是否需要使用深度对比(angular.equals())。
脏检查机制(dirty-checking)是实现双向数据绑定的重要基础。
Angular中的$digest函数:当接受view上的事件指令转发的事件时,就会切换到Angular的上下文环境,来影响这类事件,$digest循环就会触发。
$digest函数的工作过程:
遍历一遍所有的watcher函数就是一轮脏检查,执行完一轮之后,只要有watcher监听的值改变过,那么就会重新在进行一轮,直到所有的值都没有变化。从第一轮到所有数据稳定称为一个完整的$digest循环。当循环结束后,才把模型的变化结果更新到dom中去,防止频繁的dom操作。
我们已经知道什么时候以及怎么开始digest循环了,那么digest循环具体做了些什么?
在digest循环中,AngularJS会遍历整个$watch列表,所有watcher都会被触发,当一个wathcer被触发时,AngularJS会检测Scope模型相应的数据,如果它发生了变化,那么关联到该watcher的回调函数就会被触发。
如果执行了一次digest循环后某个值发生了变化,那么AngularJS会再次循环,直至不再有任何变化。这是因为你在$watch中更新某个值,如果该值对应的$watch已在这遍循环通过,AngularJS将检测不到变化无法更新。如果循环运行了10次或更多次,AngularJS会抛出异常并停止。(就算没有更新值,AngularJS也会多运行一次来确保没有改变,也就是至少运行两次)。
以上就是Angular的数据双向绑定的原理。
后面会分享更多devops和AIOps 更多干货,感兴趣的朋友可以关注下~
- 上一篇: Angular中使用表单输入的应用设计
- 下一篇: 关于737NG 发动机5级引气活门安装程序的说明
猜你喜欢
- 2024-10-12 软件质量没有银弹:阿里巴巴的25个技术实践与坑
- 2024-10-12 应对变化!盘点RSA2015十大热门产品
- 2024-10-12 Facebook宣布基于React的富文本编辑器Draft.js开源
- 2024-10-12 猪八戒当年没追到嫦娥,差的只是一个健身的距离
- 2024-10-12 办公小技巧:PPT图表也能实现交互效果
- 2024-10-12 外企必备!注塑行业术语(中英文对照)
- 2024-10-12 ionic 滚动条 ionic 滚动条 键盘
- 2024-10-12 从 Angular转到 React,网易严选的前端工程化实践
- 2024-10-12 「原神」这些字你都读对了吗-角色称号篇
- 2024-10-12 注塑机-常用注塑术语中英文对照 注塑机英语专业术语
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)