dojo源码阅读之dojo/Stateful
Posted yang_chuanlong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dojo源码阅读之dojo/Stateful相关的知识,希望对你有一定的参考价值。
dojo/Stateful是dojo中的一个基类,提供了能够观测对象属性变化的功能,Stateful 使用文档。
其基本用法如下:
var s = new Stateful(foo:8)
s._fooSetter = function(value)
this.foo = value;
;
s.watch("foo", function(name, oldValue, newValue)
console.log(`foo的值由$oldValue变为$newValue`)
)
执行 s.set("foo", 9), s._fooSetter就会被调用, 同时控制台会输出: ”foo的值由8变为9“
Stateful是如何做到上述功能的呢,Stateful.set方法, 可以看到当调用 Stateful实例的set方法时,set方法会根据要传入的name计算出setter方法, 如set('foo', 9)会找到_fooSetter方法并执行,如果使用了watch方法观察foo的变化,那么对应的callback就会被调用。
watch是如何实现的呢。Stateful.watch方法。以下面代码为例
s = new Stateful()
watchFun1 = function(name, oldValue, newValue)
console.log(`fun1 is invoked`);
;
watchFun2 = function(name, oldValue, newValue)
console.log(`fun2 is invoked`);
;
s.watch("foo", watchFun1)
s.watch("foo", watchFun2)
watch方法的实现步骤大致如下:
1, 定义_watchCallbacks 方法(一个Stateful实例只会被定义一次)。
this._watchCallbacks = function(name, oldValue, value)
.....//根据name找到对应的listener函数并执行。如foo对应的watchFun1和watchFun2.
2, this._watchCallbacks._foo = [watchFun1, watchFun2]
_changeAttrValue方法
_changeAttrValue方法用来直接改变Stateful实例的属性,而不属性对应的setter方法。
如s._changeAttrValue("foo", 9)会直接设置s.foo为9而不调用s._fooSetter, 如果使用s.set("foo", 9)则会调用。
什么情况下会用到_changeAttrValue方法呢,当Stateful实例有两个互相link的属性时。如s.bar = s.foo * 2;
当s.bar改变时s.foo也要变,而s.foo改变时s.bar也要跟着改变。这样就会形成一个无限循环。如:
s = new Stateful(
foo: 1
);
//bar = foo * 2
s._fooSetter = function(name, value)
this.foo = value;
this.set("bar", value * 2);
console.log("s._fooSetter is invoked");
s._barSetter = function(name, value)
this.bar = value;
this.set("foo", value / 2);
console.log("s._barSetter is invoked");
如果使用_changeAttrValue就可以避免这个问题。如下:
s._fooSetter = function(value)
this.foo = value;
this._changeAttrValue("bar", value * 2);
console.log("s._fooSetter is invoked");
s._barSetter = function(value)
this.bar = value;
this._changeAttrValue("foo", value / 2);
console.log("s._barSetter is invoked");
你可以像上面例子中直接Stateful实例化一个对象,但一个更好的方式是继承Stateful来实现一个子类再实例化对应的对象, 如下:
MyStateful = new declare([Stateful],
foo:1,
_fooSetter: function(value)
this.foo = value;
this._changeAttrValue("bar", value * 2);
,
bar: 2,
_barSetter: function(value)
this.bar = value;
this._changeAttrValue("foo", value / 2);
);
s = new MyStateful();
以上是关于dojo源码阅读之dojo/Stateful的主要内容,如果未能解决你的问题,请参考以下文章