或许你看过Ext JS 各种简简单单就能写出的组件,就会觉得从基础知识学起来特别的无聊,但是至少我觉得,从基础学起来会让你少走弯路,如果你没有什么项目特别着急的要使用Ext JS 那你就从头看起吧。
这篇Ext JS 的类系统也是适用于4.X的版本的。3.X的就不说了,网上大部分的Ext JS 的中文资料的都是3.X的,但是3.X的代码结构比较混乱,并且兼容性存在问题,我们公司基本上已经全线抛弃它了。
首先说命名规则,对于你的类,命名空间,文件名使用一致的命名规则,有助于组织代码,结构化并提高可读性。
类名称只能包含字母数字。数字是允许的但是不推荐,除非他们属于一个技术术语。不要使用下划线,字符,或任何其他非字母数字的字符。
类最好有合理的命名空间进行分组,并且在名字中体现出来:
MyCompany.data.CoolProxy
顶级的命名空间和最后的类名应该以驼峰方式命名,中间其他的都应该小写,比如:
MyCompany.form.action.AutoLoad
如果是你自己定义的类,请不要以Ext为顶级的命名空间,再说一点,如HTML这样的缩略词也要遵循驼峰方式命名:
MyCompany.util.HtmlParse
文件的存储路径要能根据类名直接映射到比如:
Ext.util.Observable 储存在path/to/src/Ext/util/Observable.js
其中path/to/src是指你的工程路径,所有的类都应该保持在这个共同的根目录下,最好的开发,维护,和部署经验应该有适当的命名空间。
方法和变量和类类似,名称只能包含字母数字。在大多数情况下数字是允许的但不建议,除非他们属于一个技术术语。不要使用下划线,字符,或任何其他非字母数字字符。使用驼峰式大小写,包括类似HTTP这样的缩略语,如
getHttp ()
var httpServer。
类的属性名遵循惯例方法和变量名相同,除非当他们是静态常量。静态类的属性是常量应该全部大写,例如:
Ext.MessageBox.YES = “Yes”
早于ExtJS4之前的版本 类的定义是下面这样的:
var MyWindow = Ext.extend(Object, { ... });
指的是继承自Object或者Ext.Window来创建一个类。Sencha觉得上面的方式有一些弊端,比如说在实体创建之前我就想指定一些属性,或者父类在创建实体之前就能被加载。
所以Sencha在ExtJS4之后提供了新的方式,你可以先定义一个类,再创建这个类的实体。
Ext.define(className, members, onClassCreated);
className类名, members类的变量方法等, onClassCreated类创建之后的回调函数。
下面是个包括定义和实例化的完整例子:
Ext.define('My.sample.Person', {
name: 'Unknown',
constructor: function(name) {
if (name) {
this.name = name;
}
},
eat: function(foodType) {
alert(this.name + " is eating: " + foodType);
}
});
var aaron = Ext.create('My.sample.Person', 'Aaron');
aaron.eat("Salad"); // alert("Aaron is eating: Salad");
上面的例子先用define来定义,再用Ext.create来实例化。constructor是构造方法,eat就是一个方法。
在类中的这一功能,你可以不必自定义getter,setter方法,配置在config中的属性可以又Ext知道生成。
在这里ExtJS5对于ExtJS4有一些优化,你自己的类可以不需要手动的调用initConfig().但是如果你的类继承自Ext.Base,initConfig()还是需要被调用的。
Ext.define('My.own.Window', {
extend: 'Ext.Component',
/** 只读的 */
isWindow: true,
config: {
title: '在这里写标题',
bottomBar: {
height: 50,
resizable: false
}
},
applyTitle: function(title) {
if (!Ext.isString(title) || title.length === 0) {
alert('Error: 标题title不能为空');
}
else {
return title;
}
},
applyBottomBar: function(bottomBar) {
if (bottomBar) {
if (!this.bottomBar) {
return Ext.create('My.own.WindowBottomBar', bottomBar);
}
else {
this.bottomBar.setConfig(bottomBar);
}
}
}
});
/** 再定义一个子组件. */
Ext.define('My.own.WindowBottomBar', {
config: {
height: undefined,
resizable: true
}
});
下面我们来创建一个实体:
var myWindow = Ext.create('My.own.Window', {
title: 'Hello World',
bottomBar: {
height: 60
}
});
alert(myWindow.getTitle()); // alerts "Hello World"
myWindow.setTitle('Something New');
alert(myWindow.getTitle()); // alerts "Something New"
myWindow.setTitle(null); // alerts "Error: Title must be a valid non-empty string"
myWindow.setBottomBar({ height: 100 });
alert(myWindow.getBottomBar().getHeight()); // alerts 100
通过statics来配置
Ext.define('Computer', {
statics: {
instanceCount: 0,
factory: function(brand) {
// 'this' in static methods refer to the class itself
return new this({brand: brand});
}
},
config: {
brand: null
}
});
var dellComputer = Computer.factory('Dell');
var appleComputer = Computer.factory('Mac');
alert(appleComputer.getBrand());
Sencha Touch包含一些有用的功能,帮助你调试和错误处理。
你可以使用Ext.getDisplayName()来调用任何类的方法。
throw new Error('['+ Ext.getDisplayName(arguments.callee) +'] Some message here');
ExtJS也支持类的继承,并且可以对方法进行重载,这点你要记住,这对于以后你要创建一个复杂的Window是有帮助的。
这里先列个简单的例子:一个窗口,上面有个按钮
Ext.define('Boco.reaManage.resAddPanel', {
extend: 'Ext.window.Window',
frame: false,
border : false,
draggable : true,
height : 550,
modal : true,
overflowY : 'scroll',
width : 700,
initComponent: function(){
this.items=[{
xtype:'button',
text:'保存',
handler : function(){
alert('按钮被点击了');
}
}];
this.callParent();
}
})
initComponent:就是Ext.window.Window构建组件的方法,这里我们对他进行了重载,但是要保留父类的逻辑,所以在我门自己的内容定义完了之后要在最后加入this.callParent()这句。这是一个很有用的例子。