搜索

首页  >  问答  >  正文

angular.js - 试问angularjs的双向绑定是如何实现的?

用过angularjs的人肯定知道他的双向绑定,用起来也是很方便,可是他内部是怎么实现的呢?

视图变化了去更新数据,这个还好理解,也大都知道怎么去模拟一下,但是说到数据变化了去更新视图,关键在于是怎么去判断数据发生了变化。。。

之前想了一下,类似先存储一份oldValue,然后定时去遍历这些,用newValue和oldValue去对比,如果变化了做更新和其他相关的工作。。。

但是觉得这样行吗?自己思索半天觉得也不是很靠谱,希望各位兄弟姐妹不吝教诲!## 标题

高洛峰高洛峰2745 天前585

全部回复(6)我来回复

  • PHP中文网

    PHP中文网2017-05-15 17:01:32

    实现一个类似双向绑定的简单例子

    HTML

    <input id="app" my-model="text" />
    

    SCRIPT

    var scope = {};
    var input = document.getElementById('app');
    

    视图变化更新数据

    这个很简单,编译指令myModel的时候绑定事件即可

    input.addEventListener('input', function (e) {
        scope.text = e.currentTarget.value;
    },false);

    数据变化更新UI

    scope内部有个watchers和digest

    scope.$$watchers = [];
    scope.$$watchers.push({
        key:'text',
        fn: function (value) {
            input.value = value;
        }
    });
    
    scope.$digest = function () {
        scope.$$watchers.forEach(function (watcher) {
            watcher.fn(scope.text);
        });
    };

    当我们给scope赋值的时候在触发digest,那么UI就会同步更新了

    scope.text ='zzz';
    scope.$digest();
    

    直接给scope赋值并不会更新UI,只有触发了digest,angualr才会去更新UI,大部分情况下angular帮我们主动触发了digest,给人的印象好像我们随便给scope就可以了,结果出现自己理解不了的情况。例如

    angular.module('myApp', [])
        .controller('MyCtrl', function ($scope) {
            setTimeout(function () {
                $scope.text = 'zzz';
            }, 1000);
        });
        

    直接使用setTimeout,结果UI就是不更新,需要我们做如下处理

    angular.module('myApp', [])
        .controller('MyCtrl', function ($scope) {
            setTimeout(function () {
                $scope.$apply(function () {
                    $scope.text = 'zzz';
                });
            }, 1000);
        });
        

    或者使用angular的$timeout,它帮我们触发了digest

    angular.module('myApp', [])
        .controller('MyCtrl', function ($scope,$timeout) {
            $timeout(function () {               
                $scope.text = 'zzz';
            }, 1000);
        });

    回复
    0
  • 巴扎黑

    巴扎黑2017-05-15 17:01:32

    搜索一下吧 很多文章可以给你解惑 先搜索再提问

    回复
    0
  • 巴扎黑

    巴扎黑2017-05-15 17:01:32

    首先声明一点,我对于题主提到的angularjs不太熟悉,有点不对题。
    knockout也有同样的数据数据双向绑定的特性,它是以观察者模式进行实现的,创建被观察的对象后,使用set方法赋值的时候,同时通知对该对象感兴趣的观察者,以此来达到数据双向绑定的效果。

    回复
    0
  • 伊谢尔伦

    伊谢尔伦2017-05-15 17:01:32

    angular1 是脏检查。。也因为这个带来了性能的问题

    回复
    0
  • 世界只因有你

    世界只因有你2017-05-15 17:01:32

    AngularJS 是如何实现其双向数据绑定机制的?

    回复
    0
  • 迷茫

    迷茫2017-05-15 17:01:32

    可以参考:
    http://teropa.info/build-your-own-angular/build_your_own_angularjs_sample.pdf

    回复
    0
  • 取消回复