-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEnum.js
More file actions
242 lines (221 loc) · 6.45 KB
/
Enum.js
File metadata and controls
242 lines (221 loc) · 6.45 KB
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
/**
* @file 通用枚举类,参考自ECOMFE的ER
*/
class Enum {
/**
* @class Enum
*
* 通用枚举类,用于生成一个枚举对象
*
* 枚举对象是业务系统中非常普遍使用的一个类型,其基本功能是将一个数字和具体的含义对应起来
*
* 枚举是一类数值的集合,枚举中的每一项包括3个属性:
*
* - `value`:对应原始的数字值
* - `alias`:枚举项在业务中的别名,通常使用大写字母和下划线组成的常量表达方式
* - `text`:该项显示时的文字
*
* 使用本类,可以简单地创建一个枚举对象,如:
*
* var Status = new Enum(
* { alias: 'NORMAL', text: '正常' },
* { alias: 'DISABLED', text: '禁用' },
* { alias: 'DELETED', text: '已删除' }
* );
*
* 传入的参数的`value`由0开始今次递增。对于`value`非递增的枚举,在构造时对指定的项传入`value`属性即可,如:
*
* var MouseButton = new Enum(
* { alias: 'LEFT', text: '左键', value: 1 },
* { alias: 'RIGHT', text: '右键', value: 2 },
* { alias: 'MIDDLE', text: '中键', value: 4 }
* );
*
* 枚举会维护2个映射,分别为`value`至`alias`及`alias`至`value`,因此可以简单地通过属性访问的方式获取`alias`或`value`:
*
* if (user.status === Status.DELETED) {
* warn('该用户已经删除');
* }
*
* @param {meta.EnumItem...} 枚举项
* @constructor
*/
constructor() {
this.valueIndex = [];
this.aliasIndex = {};
this.textIndex = {};
for (let i = 0; i < arguments.length; i++) {
let element = arguments[i];
if (element.value == null) {
element.value = i;
}
this.addElement(element);
}
}
/**
* 为当前枚举对象添加一个{@link meta.EnumItem 枚举项}
*
* @param {meta.EnumItem} element 待添加的枚举项
* @throws {Error} 如果`value`或`alias`存在重复则抛出异常
*/
addElement(element) {
if (this.hasOwnProperty(element.value)) {
throw new Error('Already defined an element with value' + element.value + ' in this enum type');
}
if (this.hasOwnProperty(element.alias)) {
throw new Error('Already defined an element with alias "' + element.alias + '" in this enum type');
}
this[element.value] = element.alias;
this[element.alias] = element.value;
this.valueIndex[element.value] = element;
this.aliasIndex[element.alias] = element;
this.textIndex[element.text] = element;
}
/**
* 根据数值获取枚举项
*
* @param {number} value 数值
* @return {meta.EnumItem} 对应的枚举项
*/
fromValue(value) {
return this.valueIndex[value];
}
/**
* 根据别名获取枚举项
*
* @param {string} alias 别名
* @return {meta.EnumItem} 对应的枚举项
*/
fromAlias(alias) {
return this.aliasIndex[alias];
}
/**
* 根据文字获取枚举项
*
* @param {string} text 文字
* @return {meta.EnumItem} 对应的枚举项
*/
fromText(text) {
return this.textIndex[text];
}
/**
* 根据数值获取对应枚举项的文字
*
* @param {number} value 数值
* @param {boolean} hasDefaultValue 未提供value时是否使用使用value=0
* @return {string} 对应的文字
*/
getTextFromValue(value, hasDefaultValue) {
if (hasDefaultValue && value == null) {
value = 0;
}
else if (value === null || value === '' || value === undefined) {
return '-';
}
return this.fromValue(value).text;
}
/**
* 根据文字获取对应枚举项的文字
*
* @param {string} alias 文字
* @return {string} 对应的文字
*/
getTextFromAlias(alias) {
return this.fromAlias(alias).text;
}
/**
* 根据数值获取对应枚举项的数值
*
* @param {string} alias 数值
* @return {number} 对应的数值
*/
getValueFromAlias(alias) {
return this.fromAlias(alias).value;
}
/**
* 根据文字获取对应枚举项的数值
*
* @param {string} text 文字
* @return {number} 对应的数值
*/
getValueFromText(text) {
return this.fromText(text).value;
}
/**
* 根据数值获取对应枚举项的别名
*
* @param {number} value 数值
* @return {string} 对应的别名
*/
getAliasFromValue(value) {
return this.fromValue(value).alias;
}
/**
* 根据文字获取对应枚举项的别名
*
* @param {string} text 文字
* @return {string} 对应的别名
*/
getAliasFromText(text) {
return this.fromText(text).alias;
}
/**
* 将当前枚举转换为数组,常用于下拉选择控件之类的数据源
*
* @param {...Mixed} [hints] 用于生成数组的提示信息,数组中的每一项可以为字符串或者对象,
* 为字符串时使用`alias`与字符串相同的{@link meta.EnumItem}对象,为对象时则直接将对象插入到当前位置。
* 不提供此参数则直接将枚举按`value`属性进行排序生成数组返回
* @return {meta.EnumItem[]} 每次返回一个全新的数组副本
*/
toArray() {
let array = [];
if (arguments.length > 0) {
for (let i = 0; i < arguments.length; i++) {
let hint = arguments[i];
if (typeof hint === 'string') {
array.push(this.fromAlias(hint));
}
else {
array.push(hint);
}
}
}
else {
// 必须做一次复制操作,不能让外部的修改影响枚举结构
/* eslint-disable no-redeclare */
for (let i = 0; i < this.valueIndex.length; i++) {
// 由于`value`不一定是连续的,所以一定要去除空项
if (this.valueIndex[i]) {
array.push(this.valueIndex[i]);
}
}
/* eslint-enable no-redeclare */
}
return array;
}
toSelectionObject() {
let array = this.toArray();
let aaa = array.reduce(
(options, item) => {
options[item.value] = item.text;
return options;
},
{}
)
return aaa;
}
// { label: 'Apple', value: 1 },
toCheckArray(withAll) {
let array = [];
if (withAll) {
array = [{ text: '全部', value: -1 }];
}
array = [...array, ...this.toArray()];
return array.map(
(item) => {
return { label: item.text, value: item.value, key: item.alias };
},
)
}
}
module.exports = Enum;