強大的observejs


寫在前面

各大MVVM框架的雙向綁定太難以觀察,很難直觀地從業務代碼里知道發生了什么,我不是雙向綁定的反對者,只是認為雙向綁定不應該糅合進底層框架,而應該出現在業務代碼中,或者是業務和框架之間的代碼上,由開發者實現,由開發者決定觀察什么,決定響應什么。
以及Object.observe的支持度不夠好(http://caniuse.com/#search=observe)
再者Object.observe的功能太弱(如對象內數組的變化無法監聽)。
所以就有了observejs。

observe.js意義

  • 監聽任意對象的任意數據變化
  • 作為業務和框架之間的中間件存在
  • 作為mv*框架中的監聽模塊(當然我是相當反對)

3分鍾精通observe.js

對象字面量

var obj = { a: 1 };
//watch obj
observe(obj, function (name, value) {
    console.log(name + "__" + value);//a__2 
});
obj.a = 2;

數組

var arr = [1, 2, 3];
//watch obj
observe(arr, function (name, value, old) {
    console.log(name + "__" + value+"__"+old);
});
arr.push(4);//array__push 
arr[3] = 5;//3__5

復雜對象

var complexObj = { a: 1, b: 2, c: [{ d: [4] }] };
//watch complexObj
observe(complexObj, function (name, value) {
    console.log(name + "__" + value);    //d__100 
});
complexObj.c[0].d = 100;

普通對象

var User = function (name, age) {
    this.name = name;
    this.age = age;
    //watch User's instance
    observe(this, function (name, value, oldValue) {
        console.log(name + "__" + value + "__" + oldValue);//name__wangwu__lisi 
    });
}
var user = new User("lisi", 25);
user.name = "wangwu";

原理

監聽對象

利用Object.defineProperty,以及內建 "__屬性名" 來保存真正的 "屬性名" 的值。

Object.defineProperty(target, prop, {
    get: function () {
        return this["__" + prop];
    },
    set: function (value) {
        self.onPropertyChanged(prop, value, this["__" + prop]);
        this["__" + prop] = value;
                       
    }
});

監聽數組

    observe.methods = ["concat", "every", "filter", "forEach", "indexOf", "join", "lastIndexOf", "map", "pop", "push", "reduce", "reduceRight", "reverse", "shift", "slice", "some", "sort", "splice", "unshift", "valueOf"]

    observe.triggerStr = ["concat", "pop", "push", "reverse", "shift", "sort", "splice", "unshift"].join(",")
observe.methods.forEach(function (item) {
    target[item] = function () {
        var result = Array.prototype[item].apply(this, Array.prototype.slice.call(arguments));
        for (var cprop in this) {
            if (this.hasOwnProperty(cprop) && cprop != "_super" && !observe.isFunction(this[cprop])) {
                self.watch(this, cprop);
            }
        }
        if (new RegExp("\\b" + item + "\\b").test(observe.triggerStr)) {
            self.onPropertyChanged("array", item, arguments[0]);
        }
        return result;
    };
});

對Array的所有方法進行了mock,上面的target是被監聽的array,其所有方法被重寫,然后內部執行,執行的過程中,如果屬於edit操作,如concat, pop, push等,都會觸發onPropertyChanged。

Github

https://github.com/kmdjs/observejs

現在開始,請愉快地使用吧!

This content is released under the (http://opensource.org/licenses/MIT) MIT License.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM