发表于: 2017-06-04 21:49:50
2 1288
【JS-08】
小课堂【武汉第131期】
ANGULARJS双向绑定后,发生了什么事情?是什么可以让VIEW层和CONTROLLER层进行绑定的?
分享人:庄引
目录
1.背景介绍
2.知识剖析
3.常见问题
4.解决方案
5.编码实战
6.扩展思考
7.参考文献
8.更多讨论
1.背景介绍
【JS-9】
小课堂【武汉第131期】
ANGULARJS双向绑定后,发生了什么事情?是什么可以让VIEW层和CONTROLLER层进行绑定的?
分享人:庄引
目录
1.背景介绍
2.知识剖析
3.常见问题
4.解决方案
5.编码实战
6.扩展思考
7.参考文献
8.更多讨论
单向数据绑定
单向数据绑定:指的是我们先把模板写好,然后把模板和数据(数据可能来自后台)整合到一起形成 HTML 代码,然后把这段 HTML 代码插入到文档流里面。 单向数据绑定缺点:HTML 代码一旦生成完以后,就没有办法再变了,如果有新的数据来了,那就必须把之前的 HTML 代码去掉,再重新把新的数据和模板一起整合后插入到文档流中。
双向数据绑定
双向绑定概念其实很简单,,视图(View)的变化能实时让数据模型(Model)发生变化,而数据的变化也能实时更新到视图层。
双向数据绑定的优点是无需进行和单向数据绑定的那些 CRUD(Create,Retrieve,Update,Delete)操作,双向数据绑定最经常的应用场景就是表单了, 这样当用户在前端页面完成输入后,不用任何操作,我们就已经拿到了用户的数据存放到数据模型中了。
2.知识剖析
MVC的基本概念
- 视图(View):用户界面,主要负责视图的显示。
- 控制器(Controller):业务逻辑,协调View和Model。
- 模型(Model):数据保存,主要负责数据的管理
MVC模式的意思是,软件可以分成三个部分,angularjs也是基于MVC的概念
AngularJS中的数据绑定是模型和视图之间的同步。
数据模型
AngularJS应用程序通常具有数据模型。数据模型是可用于应用程序的数据集合。
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.firstname = "John";
$scope.lastname = "Doe";
});
HTML视图
显示AngularJS应用程序的HTML容器称为视图。 视图可以访问模型,并且在视图中有几种显示模型数据的方法。 可以使用ng-bind指令,将该元素的innerHTML绑定到指定的模型属性:
<p ng-bind="firstname"></p>
您也可以使用双括号{{}}来显示模型中的内容:
<p>First name: {{firstname}}</p>
ANGULARJS CONTROLLER
AngularJS中的AngularJS控制器应用由控制器控制。 由于模型和视图的直接同步,控制器可以完全与视图分离,并且仅仅集中在模型数据上。 由于AngularJS中的数据绑定,视图将反映控制器中所做的任何更改。
3.常见问题
1.背景介绍
HTML视图
显示AngularJS应用程序的HTML容器称为视图。 视图可以访问模型,并且在视图中有几种显示模型数据的方法。 可以使用ng-bind指令,将该元素的innerHTML绑定到指定的模型属性:
<p ng-bind="firstname"></p>
您也可以使用双括号{{}}来显示模型中的内容:
<p>First name: {{firstname}}</p>
3.常见问题
1.背景介绍
HTML视图
显示AngularJS应用程序的HTML容器称为视图。 视图可以访问模型,并且在视图中有几种显示模型数据的方法。 可以使用ng-bind指令,将该元素的innerHTML绑定到指定的模型属性:
<p ng-bind="firstname"></p>
您也可以使用双括号{{}}来显示模型中的内容:
<p>First name: {{firstname}}</p>
3.常见问题
ANGULARJS双向绑定后,发生了什么事情?
- 如何监听页面View的变化?
- 如何将View的变化更新到Model?
- 如何监听Model的变化?
- 如何将Model的更新到View?
AngularJS的数据双向绑定是基于数据的脏检查机制的。大体意思上来说,就是记录所有变量的当前值,当发生某些操作之后, 通过$apply或者$digest进入脏检查环节。对比最近的一次值和现在的值是否一致,不一致则实现页面的更新,然后再执行一次直到数据不再发生变化。 首先angularJS将它自定义的html页面转化为正常的dom,相对来说就是要解析那些angularJS专有的指令。页面上的指令有compile和link阶段, compile的时候搜索匹配,然后执行指令定义时写的compile函数,link阶段将那些变量插入watch队列。触发脏检查时全部遍历一次watch队列,实现视图的更新。
什么时候会触发脏检查呢?
- DOM事件,譬如用户输入文本,点击按钮(ng-click)等
- XHR响应事件 ($http)
- 浏览器Location变更事件 ($location)
- Timer事件($timeout, $interval)
- 执行$digest()或$apply()
最后一种情况应该是统一的入口,只不过前几种情况会自动调用这个入口而已。其他情况下,用户需要手动进入脏检查的话,就要执行$digest()或$apply()了。
4.解决方案
是什么可以让VIEW层和CONTROLLER层进行绑定的?
当你在使用ng-model时,AngularJS使用$scope.$watch(视图到模型)以及$scope.$apply(模型到视图)来实现这个功能。
Angular双向绑定通过$watch,$digest,$apply实现的。
$digest()和$apply()是AngularJS中的两个核心并且有时候容易引人误解的部分。 AngularJS为我们提供了一个广为人知的令人惊叹的功能,那就是数据的双向绑定。这个功能极大的方便了我们的编码。数据绑定意味着,当视图(view)中的数据发生变化的时候, 作用域下的数据模型()也会相应的更新。同样的,无论何时,当数据模型()发生变化的时候,视图(view)也会相应的更新。那么,AngularJS是怎么做到的呢?当你写这样的一个表达式的时候( ), AngularJS在背后为这个数据模型()设置了一个监听器(watcher),正是由于这个监听器(watcher),无论何时当数据模型()发生变化的时候,视图(view)也会更新。 这个监听器(watcher)与你在AngularJS中设置的其它监听器类似(watcher)
5.编码实战
6.拓展思考
上图我们可以看到这样的关系链:
- View向Controller传递交互信息
- Controller通知Model改变数据
- View从Model获取数据显示到视图中,Model更新数据后通知View更新视图<
事实上,这是最传统的MVC结构。在这种结构下,View和Model互相持有,甚至View和Controller以及Controller和Model的关系都是千丝万缕,非常不利于维护。所以,后来的MVC发展出了新的结构。
我们来看看新的关系链:
- View向Controller传递交互信息
- Controller通知Model改变数据
- Model更新数据后通知Controller改变数据
- Controller得知数据改变后通知View更新视图
可以看到,演变出来的新MVC去掉了View和Model之间的联系,让View只与Controller交流,而Model也只与Controller交流。而这样的结构也称之为重量级视图控制器结构,除了视图部分和数据部分,其余的都交给Controller
这样可以让View和Model之间的解耦(独立)有利于项目的开发,让负责不同模块的开发人员不用担心自己的改动影响到别人的代码
7.参考文献
8.更多讨论
单向绑定较于双向绑定有什么优点?
单向绑定的优点是相应的可以带来单向数据流,这样做的好处是所有状态变化都可以被记录、跟踪,状态变化通过手动调用通知, 源头易追溯,没有“暗箱操作”。同时组件数据只有唯一的入口和出口,使得程序更直观更容易理解,有利于应用的可维护性。
脏检测的利弊
很多人对Angular的脏检测机制感到不屑,推崇基于setter,getter的观测机制,在我看来,这只是同一个事情的不同实现方式,并没有谁完全胜过谁,两者是各有优劣的。 大家都知道,在循环中批量添加DOM元素的时候,会推荐使用DocumentFragment,为什么呢,因为如果每次都对DOM产生变更, 它都要修改DOM树的结构,性能影响大,如果我们能先在文档碎片中把DOM结构创建好,然后整体添加到主文档中,这个DOM树的变更就会一次完成,性能会提高很多。
鸣谢
感谢大家观看
BY :庄引
评论