现在我们来分析一下Ext中的继承重头戏Observable,它位于Ext.util这个包下,它的意思即是观察者,使用观察者模式,EDA模式,UI组件就利用这种基于观察和事件的机制进行通信和渲染。
所有的UI组件都继承这个类,我们看看它的构造函数
|
这个构造函数不需要参数,在java中,这种父类的构造可以自动的调用默认构造函数,但是这里要注意,if(me.listeners)依赖了子类的构造行为,这在面向对象原则中似乎是一个禁忌,但是如果一个继承体现完全由一个团队维护,他们同时制定继承规则和继承规范,这也无可厚非,这里的listeners可以在子类中不提供,可以让构造出来的对象自己调用on方法来添加监听器,同理这里的events,如果子类没构造会被赋值为一个空对象。那么这个Observable构造器做了两个事,一个是看子类是否在对象上放了监听器,如果放了,就调用对象的on方法进行事件和监听的绑定,二是看子类是否在对象上放置了events,如果没有就把对象的events属性设置为一个空对象。也就是说子类是完全可以不做任何事的,子类只负责自己的数据构造和行为覆盖或追加,events在和监听器绑定之后就是一个Ext.util.Event对象的容器,见这行代码: me.events[eventName] = ce = new EXTUTIL.Event(me, eventName);也就是说,在Ext中,一个活生生的能够响应事件的对象有一个Event容器,它保存了这个对象可以响应什么事件以及事件被触发后被调用的监听器。
Observable原型上放置的方法都是子类继承的方法,子类的对象就可以在运行时调用这些方法,如下:
原型上放置了一个静态变量和一些方法,这些方法都是和事件以及监听有关,注意Observable的原型是一个新的对象直接量,它的constructor属性肯定指向的是Object,不是指向的Observable,这岂不是存在bug,我通过代码检测发现alert(Ext.util.Observable.prototype.constructor == Ext.util.Observable);的结果确实又是true,怎么回事呢?答案就在Ext.extend的那段防御性代码,大家回过去看看吧!
现在我们写一个继承Obervable的类,不过不是UI组件,而是一个领域模型,比如论坛帖子,它在被修改之后会跑出一个被修改的事件,监听器捕获这个事件将修改保存到数据库中,代码如下:
|
如果事件设置和监听绑定直接在子类完成,那么就不必显式调超类构造函数
|