Skip to content

Commit 7d847ba

Browse files
committed
添加控件安全包装类
Fixed #195
1 parent ab9c69f commit 7d847ba

File tree

6 files changed

+180
-1791
lines changed

6 files changed

+180
-1791
lines changed

jsduck/categories.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"main",
99
"ViewContext",
1010
"Control",
11+
"SafeWrapper",
1112
"InputControl",
1213
"ControlGroup",
1314
"InputCollection",

jsduck/config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"../src/main.js",
88
"../src/ViewContext.js",
99
"../src/Control.js",
10+
"../src/SafeWrapper.js",
1011
"../src/InputControl.js",
1112
"../src/Layer.js",
1213

src/SafeWrapper.js

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/**
2+
* ESUI (Enterprise Simple UI)
3+
* Copyright 2013 Baidu Inc. All rights reserved.
4+
*
5+
* @ignore
6+
* @file 控件包装类,用于模拟一个不存在的控件
7+
* @author otakustay
8+
*/
9+
define(
10+
function (require) {
11+
var u = require('underscore');
12+
var Control = require('./Control');
13+
14+
/**
15+
* 控件安全包装,模拟一个无任何功能的控件
16+
*
17+
* 在实际使用中,经常会有这样的代码:
18+
*
19+
* var panel = ui.get('panel');
20+
* if (panel) {
21+
* panel.set('content', someHTML);
22+
* }
23+
*
24+
* 为了消除这些分支,可以使用本类。本类提供控件所有的基础方法:
25+
*
26+
* - 禁用 / 启用:`enable` | `disable` | `setDisabled` | `isDisabled`
27+
* - 显示 / 隐藏:`show` | `hide` | `toggle` | `isHidden`
28+
* - 分类:`getCategory`
29+
* - 取值:`getValue` | getRawValue | `setValue` | `setRawValue`
30+
* - 子控件:`getChild` | `getChildSafely` | `addChild` | `removeChild`
31+
* - 设置值:`set` | `get` | `setProperties`
32+
* - 状态:`addState` | `removeState` | `toggleState` | `hasState`
33+
* - 事件:`on` | `off` | `fire`
34+
* - 销毁:`dispose` | `destroy`
35+
* - 生命周期:`initOptions` | `createMain` | `initStructure`
36+
* - 视图管理:`setViewContext`
37+
* - 渲染:`appendTo` | `insertBefore` | `render` | `repaint`
38+
* - 内部辅助:`isPropertyChanged`
39+
* - 已废弃:`initChildren` | `disposeChildren`
40+
*
41+
* 所有设置、改变值的方法均为空逻辑。获取值的方法根据分类有如下可能:
42+
*
43+
* - 获取字符串的方法,返回空字符串`""`
44+
* - 获取未知类型的方法,返回`null`
45+
* - 获取对象的方法,返回空对象`{}`
46+
* - 获取数组的方法,返回空数组`[]`
47+
* - 获取`boolean`值的方法,返回`false`
48+
* - {@link SafeWrapper#getCategory}返回`"control"`
49+
* - {@link SafeWrapper#getChildSafely}返回一个{@link SafeWrapper}对象
50+
*
51+
* 通常不应该直接实例化此类,通过以下方法获取此类的实例:
52+
*
53+
* - {@link ViewContext#getSafely}
54+
* - {@link Control#getChildSafely}
55+
* - {@link main#wrap}
56+
*
57+
* @extends Control
58+
* @constructor
59+
*/
60+
function SafeWrapper() {
61+
}
62+
63+
// 设置值的方法
64+
u.each(
65+
[
66+
'enable', 'disable', 'setDisabled',
67+
'show', 'hide', 'toggle',
68+
'setValue', 'setRawValue',
69+
'addChild', 'removeChild',
70+
'set',
71+
'addState', 'removeState', 'toggleState',
72+
'on', 'off', 'fire',
73+
'dispose', 'destroy',
74+
'initOptions', 'createMain', 'initStructure',
75+
'setViewContext',
76+
'render', 'repaint', 'appendTo', 'insertBefore',
77+
'initChildren', 'disposeChildren'
78+
],
79+
function (method) {
80+
SafeWrapper.prototype[method] = function () {};
81+
}
82+
);
83+
84+
// 获取值方法
85+
u.each(
86+
['isDisabled', 'isHidden', 'hasState', 'isPropertyChanged'],
87+
function (method) {
88+
SafeWrapper.prototype[method] = function () {
89+
return false;
90+
};
91+
}
92+
);
93+
94+
u.each(
95+
['getRawValue', 'getChild', 'get'],
96+
function (method) {
97+
SafeWrapper.prototype[method] = function () {
98+
return null;
99+
};
100+
}
101+
);
102+
103+
u.each(
104+
['getValue'],
105+
function (method) {
106+
SafeWrapper.prototype[method] = function () {
107+
return '';
108+
};
109+
}
110+
);
111+
112+
u.each(
113+
['setProperties'],
114+
function (method) {
115+
SafeWrapper.prototype[method] = function () {
116+
return {};
117+
};
118+
}
119+
);
120+
121+
// 特殊的几个
122+
SafeWrapper.prototype.getCategory = function () {
123+
return 'control';
124+
};
125+
126+
SafeWrapper.prototype.getChildSafely = function (childName) {
127+
var wrapper = new SafeWrapper();
128+
129+
wrapper.childName = childName;
130+
wrapper.parent = this;
131+
if (this.viewContext) {
132+
wrapper.viewContext = this.viewContext;
133+
}
134+
135+
return wrapper;
136+
};
137+
138+
require('./lib').inherits(SafeWrapper, Control);
139+
140+
/**
141+
* 空实例,是一个完全没有任何属性或状态的空的`SafeWrapper`对象,
142+
* 用于避免多次创建没啥用的实例
143+
*
144+
* @type {SafeWrapper}
145+
* @readonly
146+
* @static
147+
*/
148+
SafeWrapper.empty = new SafeWrapper();
149+
150+
return SafeWrapper;
151+
}
152+
);

test/SafeWrapper.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
define(function (require) {
2+
var Control = require('esui/Control');
3+
var SafeWrapper = require('esui/SafeWrapper');
4+
5+
describe('SafeWrapper', function () {
6+
it('should be a constructor', function () {
7+
expect(SafeWrapper).toBeOfType('function');
8+
});
9+
10+
it('should be instantiable', function () {
11+
expect(function () { new SafeWrapper(); }).not.toThrow();
12+
});
13+
14+
it('should override all methods from `Control`', function () {
15+
for (var method in SafeWrapper.prototype) {
16+
if (Control.prototype.hasOwnProperty(method)
17+
&& typeof Control.prototype[method] === 'function'
18+
) {
19+
expect(SafeWrapper.prototype[method]).not.toBe(Control.prototype[method], method);
20+
}
21+
}
22+
});
23+
});
24+
});

0 commit comments

Comments
 (0)