`
hgfghww9
  • 浏览: 50631 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

预览ExtJS 4.0的新功能/新特性:渲染组件的方式

 
阅读更多

  转载请注明Ext中文网 (http://www.ajaxjs.com)。
  ExtJS3.3的下一个版本就是4.0。--什么!?您不知道?那就让我们为你展开新一段的Ext之旅吧! 话说ExtJS Roadmap(新版本线路图)其中重要的一项就是"Rearchitected component rendering system - smaller, faster and simpler than ever before",重新编制组件的渲染架构,目标是比以前更快、更精、更容易!。--旧Ext的渲染方式不好吗?也不是,关键是没有一个统一的构建组件机制。一般来说,创建一个Ext组件,等于是各个组件的组合,例如一个toolbar+grid的配搭。如果需要创建特殊的控件,譬如一张图片加一个checkbox,Ext里面就没有这样的组件,需要我们去定义一个、创建一个。于是我们就可以以Ext.Component为基类(superclass),通过Ext的继承(Ext.extend),定义新的img和checkbox组件,当然还是以HTML标签为基础控制。我们所做的,首先是描述新控件它的结构,这种控件的结构可以称作DOM结构,或简单一点HTML结构。具体工作一般是先是声明一个div或autoEl,那往往都是DOM Script(createElement()/appendElement()……)的方法,或者更"先进"的一种方式是按照"DomHelper"的结构写HTML的JSON形式。定义结构的过程同时也是分配属性的过程,例如这个img元素是几高、几宽都在里面作说明。一般称作是分配默认参数。还有就是预留数据接口的问题,比如img的src无法一早确定。再复杂的数据接口如何规划,就上升到"数据绑定"的层面了,当定义好结构和参数等接口,就形成一个特定组件类供调用。实例化组件类时,就会将结构、参数的、外观的样式等等都注入到页面DOM内存中(若"非延时加载"),成功的话就算完成了渲染。
  尽管过去Ext还提出了组件生存周期的概念,可是它并不是一个创建组件的对象模型,较多的在回收事件句柄、修正组件内存泄漏时发挥的作用比较明显。对于一般构建组件而言,需要与浏览器原理更贴切、更直观(Straightforward)的API来支撑。或者说,针对创建自定义组件时的流程转向,提供一套围绕组件"结构/数据"、"行为/事件"、"外观/样式"这三大理论高点而实现的逻辑程序。新内容可能会很精彩,但不用急于揭开神秘的面纱,没有所谓的"神秘",上面我们回忆一下过去是怎么创建组件的,就是为了可以与4.0新方法对比一下。
  Ext内部渲染的还是比较复杂的,在Component/Container的对象模型,大肆充分应用override(或更严格地表述,属于模式中的 Template模式),又灵活地显示生命调用父类方法,远不如overload一个个方法清楚,已经是足够复杂了。详细的介绍可参考《ExtJS3详解与实践》 的第四章内容。
  是不是一定要了解Ext内部渲染才能写组件?不见得,因为Ext就是立足要避开这些复杂性,我们理解怎么有效率工作就足够了。小弟这里说多点嘛~只是想学人家抛砖引玉,呵呵。闲话休提,下面立刻介绍4.0出现的三个新的配置项参数(config items),它们是renderTpl:String/Ext.XTemplate、renderSelector:String和renderData:Object。 ExtJS 4新版所带来的改进,其中之一是改变了渲染组件所依托的div结构。div结构定义在Ext.Component.renderTpl(渲染模板)中。该 组件是什么结构的,就会在renderTpl中反映出来。创建组件时,renderTpl可以输入字符串,其字符串会作为构造器的参数送入Ext.XTemplate形成模板对象,从而借助该模板对象的属性和方法获得对组件结构的控制能力。Ext的模板类是一个功能非常强大类,可支持子模板、模板表达式等的功能。此处的模板就是勾勒整个组件的骨架脉络。
  打开源码Component.js,renderTpl一项可是除了一个"div"什么都没有了。因为这是Component基类,具体内容需要特定的子类所决定,当前就是这个div而已了。但应当指出,哪怕是一个什么内容都没有的Ext.Component,也一定会有Ext.Component类所赋予它的默认属性及其属性值。首先分派一个独一无二的id标识,保证了各个组件之间不会命名冲突,否则获取组件引用时会获取不正确;其次是组件的基本类,即。渲染过程必须分配好这些基本类,包括cls、cmpCls、baseCls和ui。  当自定义新Component时,可以覆盖原有的renderTpl:'div'配置项属性,达到新建组件结构之目的。比如上一个"一张图片加一个checkbox的控件"的例子,就是: …… renderTpl:'' ……  总之,可以预见的是,越复杂的组件伴随着越复杂的结构,因此必须谨记不时进行适当的优化。
  这里顺便插一点。我们知道,Ext渲染的组件过程中生成大量的HTML标签,成为组件的"骨架(skeleton)"。虽然都是通过脚本生成这些divs,不需要逐个div去手写,但是对性能而言毕竟只会加重负荷。创建一个普通的面板Panel,底下起码有4~6层的div,每层div都有特定的功能。同时,大量Markup的出现也会增加调试的困难。用户如果安装有firebug调试工具,打开"HTML"观察,就会看到一层层div。曾经有资深Widget作者看到过如此复杂的HTML当场感叹Ext怎么不节省一下。
  刚才的renderTpl的内容是写死的,仅作演示用,完整的一个Ext JS4.0组件创建方法如下: IconComponent = Ext.extend(Ext.Component, { iconCls: 'myIcon', renderTpl: '', initComponent: function() { Ext.applyIf(this.renderData, { blank: Ext.BLANK_IMAGE_URL, iconCls: this.iconCls }); Ext.applyIf(this.renderSelectors, { iconEl: '.' + this.iconCls }); IconComponent.superclass.initComponent.call(this); }, changeIconCls: function(newIconCls) { if (this.rendered) { this.iconEl.replaceClass(this.iconCls, newIconCls); } this.iconCls = newIconCls; } }); 有了renderSelectors不仅可以允许我们快捷地获取组件对象,而且可以比较清晰地掌握关键的内部结构,排除一些不必要的Tags。通过指定renderSelectors为具体的class属性,任何一个组件的实例,都可以借助这个renderSelectors的寻址来找到。例如组件body的renderSelectors默认为x-panel-body。
  既然明确了结构,那么接下来绑定内容实体应该是很容易的事情了。如果不要写死结构的内容,我们可以通过读写Ext.Component.renderData配置项为组件提供数据内容。只要在Ext.Component.renderData上加入了新的数据,都会视作为组件的内容数据,例如上例{blank}变为 Ext.BLANK_IMAGE_URL,iconCls变为'myIcon';只要在Ext.Component.renderSelectors上定义了任何一个字段,都会视作Ext.Element类型的引用,所以上例中我们才可以使用"this.iconEl.replaceClass(this.iconCls, newIconCls);"替换样式。
  另外,如果要对renderTpl里的某个HTML元素登记事件,l利用renderSelector获取目标HTML元素也是一个不错的主意。
  关于this.renderSelectors.iconEl怎么变为this.iconEl的原理过程,原来也是很容易理解的。见Component.js第782行: …… applyRenderSelectors: function() { var selectors = this.renderSelectors || {}, el = this.el.dom, selector; for (selector in selectors) { if (!selectors.hasOwnProperty(selector)) { continue; } this[selector] = Ext.get(Ext.DomQuery.selectNode(selectors[selector ], el)); } }, ……  新ExtJS4发布后,大家看到源码,应该会发现新的组件均会按照这种方式去定义的。采用新模式的组件是否真的会更利于组件的创建?4.0尚在翘首期盼中,暂无结论,咱们拭目以待……
  转载请注明Ext中文网 (http://www.ajaxjs.com)。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics