双向绑定---angular之watch、apply、digest原理深入分析(源码分析)

    双向绑定确实是目前主流框架比较常见的功能。backbone,angular以及vue三者在双向绑定的实现原理上有所不同。这篇文章主要就angular的双向绑定实现做深入分析。

    angular使用dirty(脏值)检查机制来实现了双向绑定,大体思路为:通过watch一遍又一遍地监听脏值也就是所说的脏值检查,当某个dirty由false变为true时,触发view重新渲染。

怪异现象:有些model改变了,但是view并没有能体现出来,没有做到双向绑定,此时需要手动触发apply方法才能OK。

    上述只是思路,不能知道具体需要做什么。watch如何工作的?apply又是怎样实现?双向分别如何实现?何时需要手动apply?技术细节如何体现优雅?下面我就这些问题从源码的层面一一深入,并最终真正理解angular双向绑定的原理以及angular的watch/apply/digest。

$scope下$watch方法介绍:

//$watch使用
$scope.value = 0;
$scope.$watch( function( ) {
    return $scope.value;
}, function( newValue, oldValue ) {
    console.log('newValue id updated!');
} );

代码-1

$watch的第一个参数实际就$scope.value,是被监听的对象,也可以写成字符串如'value'。

        此处有个细节,第一个参数没有直接写$scope.value而是用的匿名函数return了该变量。通过一个直观的举例来说明这种写法目的:

<body>
<a  href="www.a.com" onclick="return newPage()"></a>
<a  href="www.a.com" onclick="newPage()"></a>
<script>
    var newPage=function (){
        return false;
    };
</script>
</body>

代码-2

通过对两个<a>点击会发现,第一个没有跳转a.com而第二个正常跳转了。可以理解这里return的作用在于当事件中发生一些特定情况(例如此处可以理解为不满足跳转条件返回false)时,希望之后的事件方法停止执行。

继续看$watch。

$watch 的第二个参数是监听函数,当第一个参数值发生变化时,监听函数将会执行。其实$watch还有第三个参数是个boolean类型,作用是是否进行深度值检测。(需要注意的是【代码-1】中会看到我们没有改变$scope.value的值但是console里打印出“newValue is updated!”这是因为初始化时,watch认为$scope.value的值由undefined变成0,所以触发了监听事件)。

下面我们直接看angular中关于$watch的源码,已添加详细的注释辅助大家理解。

$watch: function(watchExp, listener, objectEquality) {
    var scope = this;
    //compileToFn可以判断watchExp并返回一个执行表达式的函数
    var get = compileToFn(watchExp, 'watch');
    var array = scope.$$watchers;
    //初始化一个监听对象
    var watcher = {
                fn: listener,//监听事件
                last: initWatchVal,//最后监听结果
                get: get,//调用$parse来返回执行表达式的函数可以获得表达式对于的需要监听的值
                exp: watchExp,//备份最初监听表达式
                eq: !!objectEquality//是否深度对比//两个!来处理空值或者未定义的行为远比if判断优雅很多
            };
    lastDirtyWatch = null<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值