ExtJS定义类

在ExtJS中,用户可以使用Ext.define自定义类或进行重载。此处将对其使用方法以及实现原理进行剖析。

定义一个类

定义一个新的基本类

1
2
3
4
5
6
7
8
9
10
11
12
13
Ext.define('My.awesome.Class', {
someProperty: 'something',

someMethod: function(s) {
alert(s + this.someProperty);
}

...
});

var obj = new My.awesome.Class();

obj.someMethod('Say '); // alerts 'Say something'

创建一个匿名类

1
2
3
4
5
Ext.define(null, {
constructor: function () {
// ...
}
});

创建一个包含私有类型的嵌套域

1
2
3
4
5
6
7
8
9
10
11
12
13
Ext.define('MyApp.foo.Bar', function () {
var id = 0;

return {
nextId: function () {
return ++id;
}
};
});

var bar=Ext.create('MyApp.foo.Bar');
alert(bar.nextId()); //1
alert(bar.nextId()); //2

Ext实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
define: function (className, data, createdFn) {
//如果是重载,则应用Manager.createOverride方法,否则应用Manager.create
if (data.override) {
return Manager.createOverride.apply(Manager, arguments);
}

return Manager.create.apply(Manager, arguments);
},

//创建一个新的类
create: function(className, data, createdFn) {

var ctor = makeCtor();//建立构造器
if (typeof data == 'function') {
data = data(ctor);
}

data.$className = className; //更改类名

//返回创建好的类,创建类的过程中,不仅要将自定义的类的属性和方法添加到类中,
//还需要将ext基本类的属性和方法添加到新建的类中。
return new Class(ctor, data, function() {//……});

Ext.Class = ExtClass = function(Class, data, onCreated) {
if (typeof Class != 'function') {
onCreated = data;
data = Class;
Class = null;
}

if (!data) {
data = {};
}

Class = ExtClass.create(Class, data); //先创建基于ExtClass的类的实例,添加应有的属性和方法

ExtClass.process(Class, data, onCreated); //将添加的属性和方法放至正确的位置

return Class; //返回创建好的类
};

重载类

定义基于EXT组件的重载

1
2
3
4
5
6
7
8
9
10
Ext.define('MyApp.override.BaseOverride', function () {
var counter = 0;

return {
override: 'Ext.Component',
logId: function () {
console.log(++counter, this.id);
}
};
}());

分解类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// File: /src/app/Panel.js

Ext.define('My.app.Panel', {
extend: 'Ext.panel.Panel',
requires: [
'My.app.PanelPart2',
'My.app.PanelPart3'
]

constructor: function (config) {
this.callParent(arguments); // calls Ext.panel.Panel's constructor
//...
},

statics: {
method: function () {
return 'abc';
}
}
});

// File: /src/app/PanelPart2.js
Ext.define('My.app.PanelPart2', {
override: 'My.app.Panel',

constructor: function (config) {
this.callParent(arguments); // calls My.app.Panel's constructor
//...
}
});

Ext重载类的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
createOverride: function (className, data, createdFn) {
var me = this,
overriddenClassName = data.override,
requires = data.requires,
uses = data.uses,
compat = data.compatibility,
classReady = function () {
var cls, temp;

//requires加载需要的类时机是:当前类初始化之前被加载。
if (requires) {
temp = requires;
requires = null;

Ext.Loader.require(temp, classReady);
} else {
cls = me.get(overriddenClassName);

delete data.override;
delete data.compatibility;
delete data.requires;
delete data.uses;

Ext.override(cls, data);

me.triggerCreated(className);

//uses记载需要的类的时机是,当前类初始化之后被加载。
if (uses) {
Ext.Loader.addUsedClasses(uses);
}

if (createdFn) {
createdFn.call(cls);
}
}
};

me.existCache[className] = true;

if (!compat || Ext.checkVersion(compat)) {

me.onCreated(classReady, me, overriddenClassName);
}

return me;
},