各大MVVM框架的双向绑定太难以观察,很难直观地从业务代码里知道发生了什么,我不是双向绑定的反对者,只是认为双向绑定不应该糅合进底层框架,而应该出现在业务代码中,或者是业务和框架之间的代码上,由开发者实现,由开发者决定观察什么,决定响应什么。
以及Object.observe的支持度不够好(http://caniuse.com/#search=observe),再者Object.observe的功能太弱(如对象内数组的变化无法监听)。
所以就有了observejs。
* 监听任意对象的任意数据变化
* 作为业务和框架之间的中间件存在
* 作为mv*框架中的监听模块(当然我是相当反对)
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 //只监听name,不监听age observe(this, ["name"],function (name, value, oldValue) { console.log(name + "__" + value + "__" + oldValue); }); } var user = new User("lisi", 25); user.name = "wangwu";//name__wangwu__lisi user.age=100; //什么都不发生
利用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。
https://github.com/kmdjs/observejs
现在开始,请愉快地使用吧!