数据绑定:模型到视图

Object.defineProperty

听说vuejs和avalon都是行使这种办法贯彻之。

Object.defineProperty最早是出于IE8实现的,但是IE8的兑现有许多题材又未克hack。。。所以vuejs才支撑IE9+,avalon才祭VBScript这个坏。

我们得以以Object.defineProperty里之所以getter和setter方法来定义对象的性,这个特性被存储器属性(JavaScript权威指南的翻,JavaScript高级程序设计翻译啊访器属性,英文:accessor
property)。当读取属性的上,会调用getter方法,设置属性时,就会调用setter方法。

就此,setter方法就深受了咱们无限可能,自然就好将数据的变迁体现到视图上去。我们看一个例(改自JavaScript高级程序设计的代码):

html,就一行:

<div id="bookName"></div>

js:

var bookName = document.getElementById('bookName')

var book = {
    _year: 2004,
    edition: 1
};
Object.defineProperty(book, "year", {
    get: function(){
        return this._year;
    },
    set: function(newValue){
     if (newValue > 2004) {
          this._year = newValue;
          bookName.textContent = newValue;
          this.edition += newValue - 2004;
        }
    }
});

book.year = 2005;

俺们定义了一个book对象,并于了外一个year的性能,读取year的回_year的值,设置year的时候,_year也随即变化,并且让div的textContent也予以上了新值。就如此好了简易的范到视图的绑定。

Object.observe

连下去我们只要祭出ES7底神器了——Object.observe。

Object.observe(),作为未来ECMAScript标准的平等有些,是一个用来异步监听JavaScript对象变化的方,并且无需用额外的JavaScript库。它同意监听器接受一个遵照时间顺序排列的转记录序列,这些改动记录描述了受监听目标所发变动之始末之集纳。

而是它的支撑情况就是没有那受人口兴奋了(来自Can I Use):

AngularJS 1

它们的运用越来越简明。

抑或地方的那无异修html代码,js现在凡如此:

var book = {
    year: 2004,
    edition: 1
};

var bookName = document.getElementById('bookName')

function observer(changes) {
    bookName.textContent = changes[0].object[changes[0].name];
}

Object.observe(book, observer)

book.year = 2005;

 

当book的值发生变化的时,就见面触发observer函数,设置div的价。同样好了数及模型的绑定。

脏检查

Angular和Regular都采用了脏乱差检查。

污迹检查中,都生一个watch方法来监视着多少的成形,检测到数量变化时即会硌监听的回调,在回调里处理相应的逻辑。但是我们怎么样知道数据变动了吗。

这边会见发一个digest方法,在这个办法里,检查新值和旧值是否等于,如果不顶,就会见沾监听回调。一直循环是历程,直到双方对等。

框架大多数情景下都见面自行进入digest,同时为会见暴露接口给用户,自主触发。

此处来一个简化的落实:

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
数据双向绑定揭秘)

我们可以这么以,html代码: <input type=”text”> 

js:

var $scope = new Scope();
$scope.name = 'zjzhome';

$scope.$watch(function() {
    return $scope.name;
}, function(newValue, oldValue) {
    console.log('Input value updated - it is now ' + newValue);
    element.value = $scope.name;
});

var element = document.querySelector('input');

function updateScopeValue() {
    $scope.name = 'Bob';
    $scope.$digest();
};
updateScopeValue();

乃会发觉input显示也Bob了。

此处而为能进行视图到范的绑定,只要监听input的keyup事件即可:

element.onkeyup = function() {
    $scope.name = element.value;
    $scope.$digest();
}

MVVM框架中落实多较这些复杂。了解下中心的规律对于速的支配框架的利用与否是好之。

相关文章