我想以集中控制的方式进行路由,为此我定义了一些视图,并且希望对其进行评估,就像它是以下格式的模板一样:
`this is a ${variable} in the template`
这是我的代码:
const Views = Object.freeze({
Home: {path:"/"},
Kind:{path:"/${kind}", values:{kind:{notNull:true}}},
SearchEntity:{path:"/${kind}/search/${name}", values:{kind:{notNull:true}, name:{}}},
Entity:{path:"/${kind}/shop/${eid}", values:{kind:{notNull:true}, eid:{notNull:true}}},
Issue:{path:"/${kind}/shop/${eid}/issue/${issueId}", values:{kind:{notNull:true}, eid:{notNull:true}, issueId:{notNull:true}}},
NewShop:{path:"/${kind}/newShop/${name}", values:{kind:{notNull:true}, name:{}}},
})
eval.call({kind:"myKind", eid:"myeid", issueId:"myIssueId"}, Views.Issue.path)
这显然行不通,这就是为什么我问这个问题:)
eval方法无法理解上下文:
undefined:1
/${kind}/shop/${eid}/issue/${issueId}
^
SyntaxError: Invalid regular expression flags
at Object.eval (<anonymous>)
at Object.<anonymous> (C:\Users\Zied\work\weally\src\util.js:10:6)
at Module._compile (internal/modules/cjs/loader.js:702:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:713:10)
at Module.load (internal/modules/cjs/loader.js:612:32)
at tryModuleLoad (internal/modules/cjs/loader.js:551:12)
at Function.Module._load (internal/modules/cjs/loader.js:543:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:744:10)
at startup (internal/bootstrap/node.js:240:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:564:3)
自然地,我可以使用函数而不是模板来解决问题,但是我想拥有一个更清晰易读的代码,并且我想在中间插入更多控件(例如notNull验证检查等...) )集中。所以我想使声明与执行分开
答案 0 :(得分:2)
不需要eval
-将path
属性设置为 function ,而该函数返回模板文字,并调用该函数:
const Views = Object.freeze({
Issue: {
path: ({kind, eid, issueId }) => `/${kind}/shop/${eid}/issue/${issueId}`,
values: {
kind: {
notNull: true
},
eid: {
notNull: true
},
issueId: {
notNull: true
}
}
},
});
console.log(Views.Issue.path({
kind: "myKind",
eid: "myeid",
issueId: "myIssueId"
}));
如果您不能在path
属性中放置函数,则可以使用正则表达式匹配字符串中的${varName}
并将其替换为输入对象中的相同属性:< / p>
const Views = Object.freeze({
Issue: {
path: '/${kind}/shop/${eid}/issue/${issueId}',
values: {
kind: {
notNull: true
},
eid: {
notNull: true
},
issueId: {
notNull: true
}
}
},
});
const replace = (template, obj) => template.replace(/\${(\w+)}/g, (_, varName) => obj[varName]);
console.log(replace(Views.Issue.path, {
kind: "myKind",
eid: "myeid",
issueId: "myIssueId"
}));
如果您也想验证:
const Views = Object.freeze({
Issue: {
path: '/${kind}/shop/${eid}/issue/${issueId}',
values: {
kind: {
notNull: true
},
eid: {
notNull: true
},
issueId: {
notNull: true
}
}
},
});
const replace = (template, conditions, obj) => {
const required = Object.entries(conditions)
.filter(([, { notNull }]) => notNull)
.map(([key]) => key);
if (!required.every(prop => obj.hasOwnProperty(prop))) throw new Error('required missing');
return template.replace(/\${(\w+)}/g, (_, varName) => obj[varName]);
};
console.log(replace(
Views.Issue.path,
Views.Issue.values,
{
kind: "myKind",
eid: "myeid",
issueId: "myIssueId"
}));
console.log(replace(
Views.Issue.path,
Views.Issue.values,
{
kind: "myKind",
eid: "myeid",
}));