1 ,类系统Class System
extjs4.0开始,重构了新的类系统。本教程分为以下四部分:
(1) 概述,介绍强大类系统的必要性。
(2)命名习惯,阐述extjs命名类,方法,属性,变量和文件的最佳实践。
(3)动手实践,提供详细的一步步的编码例子。
(4) 错误处理和调试。阐述异常处理技巧。
(1) 概述,介绍强大类系统的必要性。
EXTJS4.0有超过300个类。
JavaScript is a classless, prototype-oriented language. Hence by nature, one of the language's most powerful features is flexibility
JS可以采取很多不同的方式,不同的编码风格和技术完成同样的工作。但是也正是这种特性会导致无法预料的代价。没有一个统一的架构,JS代码会非常难理解,维护和重用。
基于类的编码方式仍然是面向对象中最受欢迎的。但是OOP不具备JS等语言的动态特性。
Each approach has its own pros and cons,
每一种方法都有它的优缺点。EXTJS4.0将JS和OOP的优点结合起来啦。
(2) 命名习惯
在编码中对类,变量等使用统一的命名习惯,可以使代码蛮得有组织,结构化和可读性好。。
a, 类
类名最好只包括字母,数字虽然也可以,但是EXTJS不推荐这样做。最好不要采用下划线,联字符或者其他非字母字符。
比如说:MyCompany.useful_util.Debug_Toolbar is discouraged
? ? ? ? MyCompany.util.Base64 is acceptable
类名必须采用合适的命名空间以包的形式组织起来。命名空间必须唯一。
MyCompany.data.CoolProxy
MyCompany.Application
只有最上层以及类名应该使用CamelCased,其他的都应该全小写:
MyCompany.form.action.AutoLoad
不是EXT官方发布的类严禁使用Ext作为顶级命名空间。
首字母缩写同样也应该遵守CamelCased惯例。
Ext.data.JsonProxy instead of Ext.data.JSONProxy
MyCompany.util.HtmlParser instead of MyCompary.parser.HTMLParser
MyCompany.server.Http instead of MyCompany.server.HTTP
b,源文件
类的名字应该是可以直接映射到它们存储的文件路径,因此必须一个文件只包含一个类。如:
-
Ext.util.Observable
?is stored in?path/to/src/Ext/util/Observable.js
-
Ext.form.action.Submit
?is stored in?path/to/src/Ext/form/action/Submit.js
-
MyCompany.chart.axis.Numeric
?is stored in?path/to/src/MyCompany/chart/axis/Numeric.j
path/to/src代表工程的类目录。所以类都应该位于这个根目录下。,
(3)方法和变量,类的属性
方法和变量、类的属性命名和类一样,最好也只包括字母字符 。方法和变量命名必须camelCased 。如:
- ?encodeUsingMd5() ?可以接受的;
- getHtml() 而不是getHTML()?
-
parseXmlContent() 而不是
parseXMLContent() - var isGoodName var base64Encoder var xmlReader var httpServer ? 第一单词小写
注意:类的属性如果是静态常量的时候,必须全部大写。
-
Ext.MessageBox.YES = "Yes"
Ext.MessageBox.NO = "No"
MyCompany.alien.Math.PI = "4.13"
3、动手实践
(1) 传统方法
extjs4.0以前版本中创建一个类一般是从Ext.extend()方法开始的。
var MyWindow = Ext.extend(Object, { ... });
这种方法的好处是容易创建一个继承自另一个类的新类,而不是直接继承。however, we didn't have a fluent API for other aspects of class creation, such as configuration, statics and mixins.
如:My.cool.Window = Ext.extend(Ext.Window, { ... });
如果要对这个新类设置名字空间,并且让它继承自Ext.Window。必须强调两点:
a, 在将Window指定为Mycool的属性之前,My.cool必须是一个一个已经存在的对象。
b,Ext.window在被引用之前必须存在或者加载。
第一点使用Ext.namespace(Ext.ns)解决。不爽的是你必须永远记住在Ext.extend之前加入名字空间。
Ext.ns('My.cool'); //这句不能少。 My.cool.Window = Ext.extend(Ext.Window, { ... });
为了解决第二点,在extjs4.0之前,需要包括ext-all.js,那怕我们只用到extjs框架的一小部分。
在extjs4.0中,可以通过一个方法Ext.define消除这些不足之处,基本语法如下:
Ext.define(className, members, onClassCreated);
className
: 类名members
:类的成员,以key-value形式存储在一个集合中。onClassCreated
:可选的回调方法,它将在此类所有的依赖全部准备好后调用,这个方法很多场合相当有用。Ext.define('My.sample.Person', { name: 'Unknown', constructor: function(name) { if (name) { this.name = name; } return this; }, eat: function(foodType) { alert(this.name + " is eating: " + foodType); return this; } });
var aaron = Ext.create('My.sample.Person', 'Aaron');
//
new My.sample.Person()
)同样也可以的,但是推荐Ext.create()
方法,后者可以利用动态加载机制。 aaron.eat("Salad"); // alert("Aaron is eating: Salad");
(2),配置extjs4.0引入一种专门的config属性。特点如下:配置信息完全从其他类成员封装。如果类的Gettert和Setter方法没有定义,那么在创建这些类的时候,类的配置属性的getter和setter会自动生成。
每一个config 属性还会生成一个apply方法,自动生成的setter方法会在设置值之前内部调用apply方法。如果在设置值之前 需要定制自己的业务逻辑时,可以重写这个方法。如果apply方法没有返咽一个值,相应的setter方法不会设置值。如:
Ext.define('My.own.Window', {
/** @readonly */
isWindow: true,
config: {
title: 'Title Here',
bottomBar: {
enabled: true,
height: 50,
resizable: false
}
},
constructor: function(config) {
this.initConfig(config);
return this;
},
applyTitle: function(title) {
if (!Ext.isString(title) || title.length === 0) {
alert('Error: Title must be a valid non-empty string');
}
else {
return title;
}
},
applyBottomBar: function(bottomBar) {
if (bottomBar && bottomBar.enabled) {
if (!this.bottomBar) {
return Ext.create('My.own.WindowBottomBar', bottomBar);
}
else {
this.bottomBar.setConfig(bottomBar);
}
}
}
});
使用方法如下:
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"
(3) 静态
静态成员采用static 属性设定。
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
},
constructor: function(config) {
this.initConfig(config);
// the 'self' property of an instance refers to its class
this.self.instanceCount ++;
return this;
}
});
var dellComputer = Computer.factory('Dell');
var appleComputer = Computer.factory('Mac');
alert(appleComputer.getBrand()); // using the auto-generated getter to get the value of a config property. Alerts "Mac"
alert(Computer.instanceCount); // Alerts "2"
4 错误处理和调试
采用
Ext.getDisplayName()显示任何方法的名字
?