extjs中包含了大量的控件,我们用的时候会发现这些控件的id和样式太难把握了,粗略看上去好像没有什么规律性,这也让我们为使用控件的应用程序写自动化测试带来了难题。其实,这些控件的id和样式是有规律的。
比方说:我们最简单的面板控件,他的样式和id可能如下所示:
其实这个控件id和样式是非常有规律的,如果仔细研读过源代码,可以发现每个都用模板语言写了一个模板,然后控件的id,样式生成规则都是在模板中定义的。
比如panel控件的模板定义如下:
- '<div id="{id}-body"
- class="{baseCls}-body
- <tpl if="bodyCls"> {bodyCls}</tpl>',
- ' {baseCls}-body-{ui}
- <tpl if="uiCls">',
- '<tpl for="uiCls">
- {parent.baseCls}-body-{parent.ui}-{.}
- </tpl>',
- '</tpl>"
- <tpl if="bodyStyle">
- style="{bodyStyle}"
- </tpl>>',
- '</div>'
从这里我们看出,任何一个控件的id总是我们赋值给他的id然后加上“-body"后缀,这个id是怎么来的呢?它是你在创建这个组件时候给他分配的值:比如:clusterstab,否则的话,它就会用Ext.id来自动生成一个。比如,我们的例子中,id是自己分配的:
- this.control({
- 'mainPanel':{
- afterrender:function(){
- scope.thisTab='clusterstab';
- Ext.getCmp('clusterstab').add(ext.create('widget.contentPanel',{
- id: scope.thisTab+'Panel',
- showType:scope.thisTab
- }));
见第4行和6行可以解释为什么我们的例子中控件id叫做clustertabPanel-body.
下面来谈谈样式的生成:
因为控件的复杂性,所以一个控件的样式也许有多个组成部分,我们逐一来看。
基本样式:如第2行,是${baseCls}-body,这个${baseCls}是取决于控件的类型,每个控件都有自己的定义,比如panel的样式的baseCls如下:
- baseCls : Ext.baseCSSPrefix + 'panel',
而这个Ext.baseCSSPrefix在Extjs中的buildSettings中定义:
- Ext.buildSettings = Ext.apply({
- baseCSSPrefix: 'x-',
- scopeResetCSS: false
- }, Ext.buildSettings || {});
现在联合起来看,我们知道我们面板的baseCls就是x-panel,所以写在最终页面上我们面板控件的基本样式就是x-panel-body
Body样式(面板上内容所用的样式):如第3行,它意思是如果定义了bodyCls,那么就显示bodyCls,对于面板,bodyCls的定义如下:
- initRenderData: function() {
- return Ext.applyIf(this.callParent(), {
- bodyStyle: this.initBodyStyles(),
- bodyCls: this.initBodyCls()
- });
- },
从这里看出来,样式定义在initBodyCls()方法中:
- initBodyCls: function() {
- var me = this,
- cls = '',
- bodyCls = me.bodyCls;
- if (bodyCls) {
- Ext.each(bodyCls, function(v) {
- cls += " " + v;
- });
- delete me.bodyCls;
- }
- return cls.length > 0 ? cls : undefined;
- },
所以,它是吧所有的bodyCls的内容用单字符分隔开来。
ui样式:这点类似于bodyCls,但我们例子中uiCls 没有,因为他从父类中继承来的uiCls为[]
style定义的样式:见第10-11行,他们是定义在bodyStyle中的,我们找到这段代码定义:
- initBodyStyles: function() {
- var me = this,
- bodyStyle = me.bodyStyle,
- styles = [],
- Element = Ext.Element,
- prop;
- if (Ext.isFunction(bodyStyle)) {
- bodyStyle = bodyStyle();
- }
- if (Ext.isString(bodyStyle)) {
- styles = bodyStyle.split(';');
- } else {
- for (prop in bodyStyle) {
- if (bodyStyle.hasOwnProperty(prop)) {
- styles.push(prop + ':' + bodyStyle[prop]);
- }
- }
- }
- if (me.bodyPadding !== undefined) {
- styles.push('padding: ' + Element.unitizeBox((me.bodyPadding === true) ? 5 : me.bodyPadding));
- }
- if (me.frame && me.bodyBorder) {
- if (!Ext.isNumber(me.bodyBorder)) {
- me.bodyBorder = 1;
- }
- styles.push('border-width: ' + Element.unitizeBox(me.bodyBorder));
- }
- delete me.bodyStyle;
- return styles.length ? styles.join(';') : undefined;
- },
从这里看出,它是分离出当前的bodyStyle,如果是函数的形式,那么吧调用结果(第9行)放进去,否则就用分号进行分隔(12行),然后把样式中所有的key,value用冒号进行分隔,所以最终执行的样式字符串类似于真正的css样式表的书写格式】、