我正在使用JavaScript为Web应用创建上下文菜单。菜单可以出现在许多上下文中,并且有不同的选择。我可以为每个上下文/选择使用不同的函数:
grid1_delete()
grid1_duplicate()
grid2_delete()
grid2_add()
grid2_duplicate()
并在构建菜单时硬编码。我不喜欢的事情可能是会有很多重复的代码。所以我在考虑使用调度程序函数,但这会产生可能很长的嵌套switch语句:
function contextMenuClick(context, menuItem) {
var action = menuItem.innerHTML;
switch (context) {
case 'grid1':
switch(action) {
case('delete'):
// do delete for grid1
break;
case('duplicate'):
// do duplicate for grid1
break;
default:
console.log('undefined action in contextMenuClick/grid1: ' + context);
}
break;
case 'grid2':
switch(action) {
case('add'):
// do add for grid2
break;
case('delete'):
// do delete for grid2
break;
case('duplicate'):
// do duplicate for grid2
break;
default:
console.log('undefined action in contextMenuClick/grid2: ' + context);
}
break;
default:
console.log('undefined context in contextMenuClick: ' + context);
}
呸。必须有一个更好的方法。也许调度员比它的价值更麻烦。我查看了一些the related posts,但我还没有完全了解如何将它们应用到这种情况。
答案 0 :(得分:7)
在Javascript中很少需要切换语句。通常,您可以使用字典/地图等对象直接进行查找:foo.bar
相当于foo['bar']
。
此外,对于“全局”变量,some_global_func()
相当于window.some_global_func()
,也可以写为var f = 'some_global_func'; window[f]()
:您不需要 eval
以便根据名称动态选择变量或调用函数。通常,在执行此操作时,您应该更喜欢将函数存储在对象中而不是存储在全局范围内(即在window
对象中)。
因此,假设grid1_delete
和grid2_delete
根本不同并且无法组合成通用函数,您可以执行以下操作,而无需更改代码:
var grid_actions = {
'grid1': {
'delete': function() { /* ... */ },
'duplicate': function() { /* ... */ }
},
'grid2': {
'delete': function() { /* ... */ },
'add': function() { /* ... */ },
'duplicate': function() { /* ... */ }
}
}
function contextMenuClick(context, menuItem) {
var action = menuItem.innerHtml;
if (context in grid_actions) {
if (action in grid_actions[context]) {
grid_actions[context][action]();
} else {
console.log('undefined action in contextMenuClick/' + context + ': ' + action);
}
} else {
console.log('undefined context in contextMenuClick: ' + context);
}
}
更好的解决方案是重构事物,使这些函数成为每个上下文的对象方法,如@ le dorfier建议。
答案 1 :(得分:2)
如何将实际对象引用传递给“context”而不仅仅是字符串?这样,你只有一个switch语句:
function contextMenuClick(grid, menuItem) {
var action = menuItem.innerHTML;
switch(action) {
case('delete'):
grid.delete();
break;
case('duplicate'):
grid.duplicate();
break;
}
}
更好的是,只需将处理程序直接绑定到正确的对象/方法。
答案 2 :(得分:1)
最简单的简单方法是让每个开关都包含一个包含开关的功能。
如果每个上下文都有一个对象,则可以为接受菜单作为参数的每个对象添加一个函数。
答案 3 :(得分:0)
使用eval(context +“_”+ action +“();”)的行可能会有效,但是非常危险,因为它允许你的客户端在你的脚本中执行几乎任意的函数。 (任何匹配X_Y的东西)。是。 eval主要是邪恶的。
怎么样
switch(context+"_"+action) {
case ("grid1_add"): grid1_add();
[...]
}