体会 YUI 组件中,对于其组件的配置管理十分佩服,不像平常的组件初始化管理,直接采用 Object Literal ,并在进行组件相应动作时,手动更新已创建组件的状态, YUI 采用了 YAHOO.util.Config 与事件机制(配置也要融合事件!),内部采用 封装的 Config 记录组件状态,并将内部状态改变与对应组件操作融合
1。组件操作与内部状态融合:
传统组件构建方式:
function component(config){ for(var p in config) { if(config.hasOwnPropery(p)) this[p]=config[p]; } if(this.x){ this.setX(this.x); } } component.prototype.setX=function(x){ this.el.style.left=x+"px"; this["x"]=x; }
其中 setX 可以外部调用用来操作 component 组件,函数要负责更新组件的内部状态。
YUI 简要演示方式:
function component(config){ this.cfg=new YAHOO.util.Config(this); this.cfg.addProperty("x", { handler: this._setX, suppressEvent:true }); if(config){ this.cfg.applyConfig(config, true); } this.cfg.fireQueue(); } component.prototype._setX=function(type, args, obj){ if(args[0]) this.el.style.left=args[0]+"px"; }
_setX 不被外部调用,外部直接调用 component.cfg.set("x",??);即可,YAHOO.util.Config 会负责调用实际操作函数,自动保持内部状态的一致性。
2.各个配置属性调用顺序分离
组件常常有很多属性配置,而各个属性之间往往有一定顺序依赖,比如 居中与宽度两个属性之间,必须首先设定属性的宽度,再设置居中才有意义,否则没有宽度居中也无从谈起。
传统方式 :
function component(config){ for(var p in config) { if(config.hasOwnPropery(p)) this[p]=config[p]; } if(this.width){ this.setwidth(this.width); } if(this.center) { this.setCenter(); } } component.prototype.setWidth=function(w){ } component.prototype.setCenter=function(){ }
必须在组件内部逻辑 hard code ,先设置 width 属性,再设置 居中属性。
YUI 简要方式:
function component(config){ this.cfg=new YAHOO.util.Config(this); this.cfg.addProperty("width", { handler: this._setWidth, supercedes:["center"], suppressEvent:true }); this.cfg.addProperty("center", { handler: this._setCenter, suppressEvent:true }); if(config){ this.cfg.applyConfig(config, true); } this.cfg.fireQueue(); } component.prototype._setWidth=function(type, args, obj){ } component.prototype._setCenter=function(type, args, obj){ }
其中只要指定其中 width 属性 supercedes 与 center 属性即可,并制定好各个属性的操作函数,那么在 fireQueue 时,会按照指定的顺序统一处理这些属性,将属性依赖配置与具体组件代码分离,以后添加更多的属性以及他们之间的依赖也不需要大规模修改组件代码,手工添加属性顺序依赖。
3.总结
短短一段 YAHOO.util.Config,彻底贯彻了现代web设计中 分离 的理念,将内部状态与操作,配置依赖与代码逻辑用 Config 做为桥梁解除耦合,使得组件具有良好的可扩展性与可维护性,希望有时间能够在自己的组件设计 中实践重构。
附录 YAHOO.util.Config 源码 .