近日,看了玉伯写的《构建前端UI组件的新思路》一文,让我追忆起去年自己分享的一篇P文《随感协同开发的JS设计模式》 ,有几分共鸣……
话说去年支付宝新版收银台项目中,我就小试了一把这种组件编码模式,点滴心得,这里和大家做一个交流:
回顾一下之前说到的抽象类,对设计模式有所了解的同学可能会觉得有些眼熟,没错,初一看,觉得它很像一个抽象工厂,但是结合下面的基础类来看,你会发觉我并没有在各基础类中,重写getVessel,show,hide等方法,而是直接继承了抽象类中的这些方法。一定会有人不解为什么要这么做,无他,就因为他是JS,而非JAVA。一定的偶合度换来足够的灵活在我看来一点都不过分,更何况这个抽象类是必须确保绝对稳定的,他在成形后不允许被随意修改那是必须的。
AP.widget.basic = new AP.Class({ setOptions:function(options){ //接口设置 }, initialize:function(targets,options){ //初始化方法,目的是建立targets子集元素和某方法的关联 }, getVessel:function(target){ //获取满足target映射关系的容器 }, bindEvents:function(target,vessel){ //这里绑定target的触发动作 }, action:function(){ //target绑定的事件触发的执行函数,包含你要执行的逻辑 }, show:function(){ //显示容器 }, hide:function(){ //隐藏容器 }, setInterface:function(){ //设置各组件共用接口 } })
通过这个抽象类,我把一个触点对象和一容器对象做了关联,通过action方法去实现他们之间最简单的交互行为。“最简单”,那么无非就是显示或者隐藏之类的操作了,所以我又定义了show,hide方法。很明显“最简单”的交互行为没办法满足100%的用户行为,所以我必须设置一个setInterface方法,在需要特殊交互效果的类中去添加效果类。最后避免大家使用时直接实例化这个抽象类,在action方法中提醒大家,如要实例化操作,请到特定的继承类中去重写action方法。
通过这个抽象类,我们可以继承出最基础的aPop,dropDown,xbox,xTab等组件…这些上篇p文中已经有提到,这里不多说,着重解释一下在这写基础类满足不了特殊需求时,我们该如何快速的进行个性化组件开发。
下面以xTab为例,我们可以用这个组件完成基础的多触点多容器之间的切换效果,但是如果在这基础上需要再加一些动画效果又该怎么办呢?先看看继承类tab的实现代码:
AP.widget.xTab = AP.widget.basic.extend({ bindEvents:function(target,vessel){ E.on(target,this.options.eventType,this.action,target,this); E.on(window,'load',this.oXtab,target,this); }, action:function(e,target){ this.switchTab(e,target); }, switchTab:function(e,target){ ... for(i=0,len=tabs.length;i<len;i++){ var hash = tabs[i].href.split("#")[1]; var vessel = D.get(hash + 'Extend'); if(vessel){ this.hide(vessel); } D.removeClass(tabs[i].parentNode,'current'); if(target.href == tabs[i].href){ D.addClass(target.parentNode,'current'); if(vessel){ this.show(vessel); } //设置各类应用接口 this.setInterface(target,vessel); } E.preventDefault(e); } }, showTab: function(index){ ... }, //初始化定位tab oXtab:function(target,e){ ... } });
可以发现我在show方法之后执行了setInterface方法,这里默认会调用抽象类中的同名方法,这个接口方法是为同类交互行添加附加的交互效果类而设的。打个比方:现在要处理一个slideTab的效果,那么我们只需要基于xTab做一个应用类的继承,覆盖setInterface方法,添加一个实现slide效果的动画类就ok了!
AP.widget.animTab = AP.widget.xTab.extend({ setInterface:function(target,vessel){ this.parent(target,vessel); this.anim(vessel); }, anim:function(vessel){ ... } }); 说实在的,这是挺土的一种设计思路,不过可以让我们换一种角度去思考组件的编码模式,以上只是粗浅的一些应用尝试,精彩还会继续…waiting for you!
转载:http://ued.alipay.com/2010/06/proposed-front-end-ui-components-and-then-build-a-new-train-of-thought/
本文链接:http://www.blueidea.com/tech/web/2010/7745.asp
出处:前端技术
责任编辑:bluehearts
◎进入论坛网页制作、WEB标准化版块参加讨论,我还想发表评论。
|