美文网首页angularjs
angularjs 数据双向绑定简洁源码实现

angularjs 数据双向绑定简洁源码实现

作者: 盛佳人 | 来源:发表于2017-04-18 19:52 被阅读18次
    hello.html
    <html>
    <head>
    <title>我的第一个 HTML 页面</title>
    </head>
    <body>
        <input ng-model="name" />
        <span>{{name}}</span>
        <script type="text/javascript" src="hello.js"></script>
    </body>
    </html>
    
    hello.js
    
    var Scope = function( ) {
        this.$$watchers = [];   
    };
    
    Scope.prototype.$watch = function( watchExp, listener ) {
        this.$$watchers.push( {
            watchExp: watchExp,
            listener: listener || function() {}
        } );
    };
    
    Scope.prototype.$digest = function( ) {
        var dirty;
        do {
                dirty = false;
    
                for( var i = 0; i < this.$$watchers.length; i++ ) {
                    var newValue = this.$$watchers[i].watchExp(),
                        oldValue = this.$$watchers[i].last;
    
                    if( oldValue !== newValue ) {
                        this.$$watchers[i].listener(newValue, oldValue);
    
                        dirty = true;
    
                        this.$$watchers[i].last = newValue;
                    }
                }
        } while(dirty);
    };
    
    //angularjs从这里开始
    var $scope = new Scope();
    
    //初始化的时候,我定义了一个name,我希望他显示在页面上
    $scope.name = '简书';
    //所以在页面上我写了一个<span>{{name}}</span>,<input ng-model="name"/>,我会找到{{name}},或者ng-model="name"等然后用$scope.name的值替换他们
    var modelList1 = [];//ng-model
    var modelList2 = [];//{{}}
    var spanList = document.querySelectorAll('span');
    for(var i =0;i<spanList.length;i++) {
        if(spanList[i].innerHTML === '{{name}}') {
            spanList[i].innerHTML = $scope.name;
            modelList2.push(spanList[i]);
            //console.log(spanList[i].innerHTML);
        }
    }
    //input
    var inputList = document.querySelectorAll('input');
    for(var i =0;i<inputList.length;i++) {
        
        if(inputList[i].attributes["ng-model"].value === 'name') {
            //初始化
            inputList[i].value = $scope.name;
            modelList1.push(inputList[i]);
            
            //ng-model绑定事件
            inputList[i].onkeyup = (function(i) {
                return function() {
                    $scope.name =  inputList[i].value;//视图到模型
                    $scope.$digest();//模型到视图
                }
            })(i);
            
            //加个$watch事件,并加入到$$watchers队列中
            $scope.$watch(function(){
                return $scope.name;
            }, (function(i) {
                return function( newValue, oldValue ) {
                    //console.log('新值 ' + newValue);
                    //console.log('旧值 ' + oldValue);
                    //ng-model
                    for(var j=0;j<modelList1.length;j++) {
                        modelList1[j].value = $scope.name;
                    }
                    //{{}}
                    for(var j=0;j<modelList2.length;j++) {
                        modelList2[j].innerHTML = $scope.name;
                    }
            }
            })(i) );
            
            
        }
    }
    //以上是初始化阶段,数据已经反应到视图上了,angularjs对应的应该是$compile+$rootScope+相关指令加事件和替换 进行编译然后渲染
    
    
    //接下来是数据的双向绑定阶段
    //我觉得应该是ng-model指令绑定的onkeydown起作用的,它起到监听赋值的操作。然后立即调用$digest()->$$watchers来实现模型到视图的数据变化
    
    
    setTimeout(function(){
        updateScopeValue();
    },3000);
    var updateScopeValue = function updateScopeValue( ) {
        $scope.name = '我是自动三秒后变化的值';
        $scope.$digest();
    };
    

    相关文章

      网友评论

        本文标题:angularjs 数据双向绑定简洁源码实现

        本文链接:https://www.haomeiwen.com/subject/hieqzttx.html