我正在构建一个涉及许多不同类型数据的通量应用以及资源的CRUD样式修改。这导致了大量的动作类型。他们中的大多数遵循相同的模式, REQUEST_ENTITY, REQUEST_ENTITY_SUCCESS, REQUEST_ENTITY_ERROR
等。
如何将它们分成名称的常数?
理想情况下,而不是像:
那样访问它们ActionTypes.REQUEST_ENTITY
我可以以更理智的方式访问它们,例如
ActionTypes.entity.REQUEST
为什么不跳过常数,而只使用字符串值?当然,您可能会不时误解一个,但是您可以很容易地将常数名称误认为,对吗?无论哪种方式,您的单位测试都会在同一位置失败,您会知道出了什么问题。
没有编译时间检查,这些常数列表的主要价值是代码有些自我记录,但是如果您在命名约定中保持一致,则可能不值得额外的努力将它们全部写成常数?
(我想那是一种非答案,但是我与他人进行了同样的对话,因此也可能值得在这里添加讨论。)
您可以简单地合并多个对象(也许从不同的文件导出)中ActionTypes
。
// entity_actions.js
module.exports = {
entity: {
REQUEST: "entity.REQUEST",
DELETE: "entity.DELETE",
}
};
// user_actions.js
module.exports = {
user: {
REQUEST: "user.REQUEST",
DELETE: "user.DELETE",
}
};
// actions.js
var entityActions = require("./entity_actions");
var userActions = require("./user_actions");
var ActionTypes = Object.assign({}, entityActions, userActions);
如果您的环境中没有Object.assign
,则可以使用Underscore#extend
或Object-Assign之类的东西。
我个人使用了一个小模块,我称为nestedKeyMirror
,该模块采用一个大嵌套对象,并根据嵌套自动生成值:
function nestedKeyMirror(obj, namespace) {
namespace = namespace || [];
for (key in obj) {
if (obj.hasOwnProperty(key) && obj[key] === null) {
obj[key] = namespace.concat([key]).join(":");
} else if (obj.hasOwnProperty(key) && typeof obj[key] === "object") {
obj[key] = nestedKeyMirror(obj[key], namespace.concat([key]));
}
}
return obj;
}
例如,在一个应用中,我定义了以下操作类型:
var actionTypes = nestedKeyMirror({
LAYOUT: {
RESIZE_PANE: null
},
CANVAS: {
SET_PROPERTY: null
},
SHAPES: {
ADD: null,
SET_PROPERTY: null,
SEND_BACKWARD: null,
SEND_FORWARD: null,
SEND_TO_BACK: null,
SEND_TO_FRONT: null
},
SELECTION: {
SELECT: null,
DESELECT_ALL: null
},
HISTORY: {
ADD: null,
SELECT_INDEX: null
}
});
这将给出,例如,actionTypes.SHAPES.ADD
具有"SHAPES:ADD"
的自动生成的字符串值。该技术可以与上面的对象合并策略结合在一起,以轻松创建深度嵌套的动作类型常数。
[更新:看起来有人最近发布了一个包装,该软件包在NPM上进行嵌套键镜像:Keymirror-nested]
如果问题是您的所有操作类型看起来都相似,则可以轻松地创建一个函数来生成它们(ES6计算的属性语法此处使用):
function generateActionType(type, base) {
return {
[base]: `${base}_${type}`,
[`${base}_SUCCESS`]: `${base}_${type}_SUCCESS`,
[`${base}_ERROR`]: `${base}_${type}_ERROR`
};
}
ActionTypes.entity = {};
Object.assign(ActionTypes.entity, generateActionType("ENTITY", "REQUEST"));
Object.assign(ActionTypes.entity, generateActionType("ENTITY", "DELETE"));
ActionTypes.entity.REQUEST_SUCCESS === "REQUEST_ENTITY_SUCCESS";