UI库

一个UI组件库,有利于理解原型链继承,遂整理至此。

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/************ 框架部分 ************/
var ui = {
version:'0.0.1',
isArray: $.isArray,
isObject: $.isPlainObject,
/**
* extend方法注意点:
* 1、最终返回的是组件的constructor方法
* 2、constructor方法继承至ui.comp.prototype
* 3、constructor方法的superclass也指向ui.comp.prototype
* 4、extend第二个入参的所有方法,都会继承到constructor的原型上
*/
extend: function() {
var io = function(o) {
for (var m in o) this[m] = o[m];
};
var oc = Object.prototype.constructor;
return function(a,b,c) {
if (a == '') a = ui.comp;
else if (typeof a == 'string'){
//ui.require(a);
a = ui.comp[a];
}
if (ui.isObject(b)){
c = b;
b = a;
a = c.constructor != oc ? c.constructor: function() {
b.apply(this, arguments);
};
}
var F = function() {},
ap,
bp = b.prototype;
F.prototype = bp;
ap = a.prototype = new F();
ap.constructor = a;
a.superclass = bp;
if (bp.constructor == oc) bp.constructor = b;
a.override = function(o) {
ui.override(a, o);
};
ap.superclass = ap.supr = (function() {
return bp;
});
ap.override = io;
ui.override(a, c);
a.extend = function(o) {
return ui.extend(a, o);
};
return a;
};
}(),
draw: function(confObj) {
var rtn = [];
if(!ui.isArray(confObj))confObj = [confObj];
for (var i = 0; i < confObj.length; i++) {
var cls = confObj[i].renderer;
if (!cls) {
throw new Error('Could not find property renderer!');
return false;
}
else {
/**
* 1、先执行ui.comp[cls](confObj[i])
* 2、再执行draw方法
*/
rtn[rtn.length] = new ui.comp[cls](confObj[i]).draw();
}
}
return (rtn.length == 1)?rtn[0]:rtn;
},
override: function(a, b) {
if (b) {
var p = a.prototype;
for (var prop in b) p[prop] = b[prop];
}
}
};
ui.comp = function() {
this.description = 'UI Base Class';
/**
* _f的作用
* 1、JS顺次执行,执行_f时,this下是没draw方法
* 2、向this的原型链上查找draw方法
* 3、因为ui.comp.Block.superclass.constructor.apply(this, arguments);
* 的关系,此时this原型链的draw方法就是组件定义的draw方法
* 4、将组件的draw方法保存在_f变量上
*/
var _f = this.draw;
this.draw = function() {
console.log('comp里的draw方法');
/**
* 1、先执行ui.comp的draw方法
* 2、因为_f保存了组件的draw方法,所以可以执行组件里的方法
*/
try {
var rtn = _f.call(this);
}
catch(ex){
throw new Error('ui.comp.'+this.description +ex);
}
return rtn;
}
return this;
};
/************ 组件部分 ************/
ui.version.Block = '1.0';
ui.comp.Block = ui.extend('', {
constructor: function(param){
/**
* 关键步骤:改变了运行时ui.comp的this指向,这样ui.comp的原型链上,
* 才有组件的方法,包括draw方法
*/
ui.comp.Block.superclass.constructor.apply(this, arguments);
for(var p in param)this[p] = param[p];
this.description='Block';
},
draw:function(){
console.log("开始绘制");
return this;
}
});
/************ 实例部分 ************/
var p_block = ui.draw({
renderer: 'Block',
margin: true,
inline: true,
width: 5
});