这是JavaScript专家的实现细节问题.
我有一个具有许多字段的UI,其中字段的值以七位输入的值复杂地依赖.当用户看到更多应用程序时,应该为可能定期更改的128个值中的任何一个显示什么?
现在,我已经通过if-then-else梳子将其作为决策树来实现,但是在需求变化下它很脆弱,而且很难做到.
我想到的一种实现方法是创建一个从0x0到0x7F的值数组,然后在每个位置存储一个闭包 -
var tbl; // initialize it with the values
...
tbl[0x42] = function (){ doAThing(); doAnotherThing(); }
Run Code Online (Sandbox Code Playgroud)
然后用它来调用它们
tbl[bitsIn]();
Run Code Online (Sandbox Code Playgroud)
这至少使决策逻辑成为一堆任务.
问题:有更好的方法吗?
(更新:神圣的废话,关于'ajax iphone标签'的那条线如何进入那里?难怪它有点令人费解.)
更新
所以发生了什么事?基本上我采取了第四种选择,虽然类似于我检查过的那种.逻辑非常复杂,我最终构建了一个Python程序来在服务器中生成真值表(生成Groovy代码,实际上,主机是Grails应用程序)并将决策逻辑完全移入服务器.现在JavaScript方面只是解释包含各个字段值的JSON对象.
最终,这可能会经历一次迭代,并成为数据库表中的数据,由位向量索引.
桌子驱动部分肯定是要走的路; 显示的具体要求已经有六个新的变化.
我看到两个选择......
两种解决方案的共同点是以下命名函数:
function aThing() {}
function anotherThing() {}
function aThirdThing() {}
Run Code Online (Sandbox Code Playgroud)
切换方式
function exec(bits) {
switch(bits) {
case 0x00: aThing(); anotherThing(); break;
case 0x01: aThing(); anotherThing(); aThirdThing(); break;
case 0x02: aThing(); aThirdThing(); break;
case 0x03: anotherThing(); aThirdThing(); break;
...
case 0x42: aThirdThing(); break;
...
case 0x7f: ... break;
default: throw 'There is only 128 options :P';
}
}
Run Code Online (Sandbox Code Playgroud)
地图方式
function exec(bits) {
var actions = map[bits];
for(var i=0, action; action=actions[i]; i++)
action();
}
var map = {
0x00: [aThing, anotherThing],
0x01: [aThing, anotherThing, aThirdThing],
0x02: [aThing, aThirdThing],
0x03: [anotherThing, aThirdThing],
...
0x42: [aThirdThing],
...
};
Run Code Online (Sandbox Code Playgroud)
在这两种情况下你都会打电话
exec(0x42);
Run Code Online (Sandbox Code Playgroud)
您是否考虑过在服务器上生成决策树而不是手动编写?使用任何干净、易于使用的表示形式,然后对其进行修改,然后将其编译为客户端的丑陋但高效的 JavaScript。
决策树很容易表示为数据,并且作为传统的树数据结构很容易理解和使用。您可以以任何对您有意义的形式存储所述树。将其作为数据进行验证和修改也应该是直接的。
然后,当您需要使用决策树时,只需将其编译/序列化为 JavaScript,作为一个大的 if-theelse、switch 或 hash 混乱。这也应该相当简单,并且可能比尝试维护switch数百个元素容易得多。