AngularJS 脏检查机制

发布时间:2017-1-25 1:19:09 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"AngularJS 脏检查机制 ",主要涉及到AngularJS 脏检查机制 方面的内容,对于AngularJS 脏检查机制 感兴趣的同学可以参考一下。

写在开头

关于Angular脏检查,之前没有仔细学习,只是旁听道说,Angular 会定时的进行周期性数据检查,将前台和后台数据进行比较,所以非常损耗性能。

这是大错而特错的。我甚至在新浪前端面试的时候胡说一通,现在想来真是羞愧难当! 没有深入了解就信口开河实在难堪大任。

最后被拒也是理所当然。

在剖析之前,非常感谢坐镇苏宁的徐飞,现在已经不在苏宁了,我也是在他翻译的文章(Build Your own AngularJS)和博客才略懂一二。
徐飞关于知乎问题国内前端团队分布和前景是怎样的?的回答也是特别有意思。

误区纠正

首先纠正误区,Angular并不是周期性触发藏检查。
只有当UI事件,ajax请求或者 timeout 延迟事件,才会触发脏检查。
为什么叫脏检查? 对脏数据的检查就是脏检查,比较UI和后台的数据是否一致!
下面解释:

$watch 对象。

Angular 每一个绑定到UI的数据,就会有一个 $watch 对象。
这个对象包含三个参数

watch = {    name:'',      //当前的watch 对象 观测的数据名    getNewValue:function($scope){ //得到新值        ...        return newValue;        },    listener:function(newValue,oldValue){  // 当数据发生改变时需要执行的操作        ...    }}

getNewValue() 可以得到当前$scope 上的最新值,listener 函数得到新值和旧值并进行一些操作。

而常常我们在使用Angular的时候,listener 一般都为空,只有当我们需要监测更改事件的时候,才会显示地添加监听。

每当我们将数据绑定到 UI 上,angular 就会向你的 watchList 上插入一个 $watch。
比如:

<span>{{user}}</span><span>{{password}}</span>

这就会插入两个$watch 对象。
之后,开始脏检查。
好了,我们先把脏检查放一放,来看它之前的东西
??
双向数据绑定 ! 只有先理解了Angular的双向数据绑定,才能透彻理解脏检查 。

双向数据绑定

Angular实现了双向数据绑定。无非就是界面的操作能实事反应到数据,数据的更改也能在界面呈现。
界面到数据的更改,是由 UI 事件,ajax请求,或者timeout 等回调操作,而数据到界面的呈现则是由脏检查来做.
这也是我开始纠正的误区
只有当触发UI事件,ajax请求或者 timeout 延迟,才会触发脏检查。
看下面的例子

<div ng-controller="CounterCtrl">    <span ng-bind="counter"></span>    <button ng-click="counter=counter+1">increase</button></div>
function CounterCtrl($scope) {    $scope.counter = 1;}

毫无疑问,我每点击一次button,counter就会+1,因为点击事件,将couter+1,而后触发了脏检查,又将新值2 返回给了界面.
这就是一个简单的双向数据绑定的流程.
但是就只有这么简单吗??
看下面的代码

'use strict';var app = angular.module('app', []);app.directive('myclick', function() {    return function(scope, element, attr) {        element.on('click', function() {            scope.data++;            console.log(scope.data)        })    }})app.controller('appController', function($scope) {    $scope.data = 0;});
    <div ng-app="app">        <div ng-controller="appController">            <span>{{data}}</span>            <button myclick>click</button>        </div>    </div>

点击后,毫无反应.
???

试试在 console.log(scope.data) 后面添加 scope.$digest(); 试试?
很明显,数据增加了。如果使用$apply () 呢? 当然可以(后面会接受 $apply 和 $digest 的区别)

为什们呢?
假设没有AngularJS,要让我们自己实现这个类似的功能,该怎么做呢?

<body>    <button ng-click="increase">increase</button>    <button ng-click="decrease">decrease</button>    <span ng-bind="data"></span>    <script src="app.js"></script></body>
window.onload = function() {    'use strict';    var scope = {        increase: function() {            this.data++;        },        decrease: function decrease() {            this.data--;        },        data: 0    }    function bind() {        var list = document.querySelectorAll('[ng-click]');        for (var i = 0, l = list.length; i < l; i++) {            list[i].onclick = (function(index) {                return function() {                    var func = this.getAttribute('ng-click');                    scope[func](scope);                    apply();

上一篇:[Now] Deploy a Node project with Zeit’s Now
下一篇:EF Fluent API上

相关文章

相关评论