引言和数据绑定相关指令1 代码实现2 代码解释双向绑定是如何实现的1 双向绑定原理watch 队列2 双向绑定原理digest循环3 双向绑定原理apply方法总结
在上一篇博客中我们介绍了两个指令,一个是ng-app,另外一个是ng-init,其中前一个是指令angularjs的作用域,第二个指令是设置angular初始化变量的,在本片博客中,我们将会介绍一下和数据绑定相关的指令,其中一个是ng-model,另外一个是ng-bind。
我们通过html输出数据可以通过两种方式,一种是通过表达式,一个是可以通过ng-bind指令,如何将我们的数据绑定到angularjs的变量呢?我们可以通过ng-model指令,ng-model指令可以实现双向绑定,也就是说:如果我们通过ng-model修改了变量的值,将会直接修改到html。
input标签,然后绑定到angular变量上<html ng-app><head> <script src="js/angular.js"></script></head><body> <input type="text" ng-model="test"><br> {{test}}<br> <div ng-bind="test"></div></body></html>运行结果
ng-model指令创建了一个变量test然后我们通过{{}}表达式,输出了test变量我们通过标签输出了test变量,注意,当我们使用ng-bind指令时,实际上是添加了innerHTML属性,如下图所示 
ng-bind指令相对于{{}}(表达式)的优势,当浏览器加载比较慢的时候,浏览器会出现{{}}符合,而ng-bind不会出现
在上面的程序的时候,我们肯定会有一个疑问:为什么我们输入文本框,下面的信息会相应改变呢?也就是说双向绑定是如何实现的?接下来我们就用文字描述一下双向绑定是如何实现的?
$watch 队列) 在angularjs中有一个$watch 队列的概念,$watch 队列中存放一系列的$watch对象,那么$watch对象是如何产生的呢?每当我们绑定数据到UI上时,会自动生成一个$watch对象,然后将$watch对象存放到$watch 队列中,如下面的代码:
代码中生成了两个变量每一个是user,一个是pass,该变量绑定到了UI上,因此会自动生成两个$watch对象,然后存放到$watch 队列中。
接下来我们再看第二段的代码:
app.controller('MainCtrl', function($scope) { $scope.foo = "Foo"; $scope.world = "World";});Hello, {{ world}}这里,即便我们在$scope上添加了两个变量,但是只有一个绑定在了UI上,因此在这里只生成了一个$watch对象。
$digest循环) 浏览器一直在等待事件,比如用户交互。假如你点击一个按钮或者在输入框里输入东西,事件的回调函数就会在javascript解释器里执行,然后你就可以做任何DOM操作,等回调函数执行完毕时,浏览器就会相应地对DOM做出变化。 Angular拓展了这个事件循环,生成一个angular context的执行环境。当浏览器接收到可以被angular context处理的事件时,$digest循环就会触发。$digest循环是由两个更小的循环组合起来的。一个处理evalAsync队列,另一个处理$watch队列,$digest将会遍历我们的$watch队列,通过$watch队列来观察我们UI中变量值是否已经发生了改变,通过$watch队列来观察我们UI中变量值是否已经发生了改变,通过$watch队列来观察我们UI中变量值是否已经发生了改变(重要的话说三遍)如果$watch队列发生了改变,那么当$digest循环结束时,DOM相应地变化。从而实现了数据的双向绑定。
$apply方法) 这时候我们又会有一个问题:什么事件可以被angular context处理呢?答案是$apply方法,我们是通过$apply方法启动$digest循环,只要$digest循环被执行,DOM元素就会被更新,假设我们有这么一个输入框ng-model="foo",然后我们输入一个f ,实际上是这么执行的$apply("foo = 'f';"),也就是ng-model指令帮我们自动调用了$apply方法。 在上面的例子中$apply方法是自动调用的,同样我们可以人为的调用$apply方法,这将在以后的博客中介绍。同样我们可以人为的创建$watch,然后将其添加到$watch队列中,这也将在以后的博客中介绍
在本篇博客中介绍了和数据绑定相关的指令,主要介绍了ng-model,ng-bind,还用文字介绍了数据的双向绑定是如何实现的。
新闻热点
疑难解答