我正在创建一个Java库的GWT版本,它支持javax.script.ScriptEngine通过Javascript动态评估函数,例如,
o => o % 2 == 0
在运行时,“o”的值是通过javax.script.Bindings定义的(o =>
部分当然被剥离了。)
问题是,如何从GWT中获得相同的效果?我使用原生函数
native Object nativeEval(String script) /*-{
return $wnd.eval(script);
}-*/
nativeEval("o % 2 == 0");
但是如何将值绑定到标识符“o”?
答案 0 :(得分:0)
将值传递给标识符“o”:
public native void define(String handle, Object o) /*-{
eval("var " + handle+ "="+ o);
}-*/;
public native boolean nativeEval(String script) /*-{
return eval(script);
}-*/;
然后称之为:
String script = "o % 2 == 0";
define("o",2);
Window.alert(nativeEval(script)+"");
define("o",3);
Window.alert(nativeEval(script)+"");
答案 1 :(得分:0)
我想我找到了一个解决方案:
import javax.script.bindings.Bindings;
import javax.script.bindings.SimpleBindings;
int bindSequence;
native void prepareOnWindow(int index) /*-{
$wnd["mylib_bindings_" + index] = new Array();
}-*/;
native void setOnWindow(int index, String name, Object value) /*-{
$wnd["mylib_bindings_" + index][name] = value;
}-*/;
native void clearOnWindow(int index) /*-{
$wnd["mylib_bindings_" + index] = null;
}-*/;
native Object invoke(String script) /*-{
var result = $wnd.eval(script);
if (typeof(result) == "boolean") {
return result ? @java.lang.Boolean::TRUE : @java.lang.Boolean::FALSE;
} else
if (typeof(result) == "number") {
return @java.lang.Double::valueOf(D)(result);
}
return result;
}-*/;
public Object invoke(String script, Bindings bindings) {
int seq = bindSequence++;
try {
StringBuilder script2 = new StringBuilder();
prepareOnWindow(seq);
for (Map.Entry<String, Object> e : bindings.entrySet()) {
setOnWindow(seq, e.getKey(), e.getValue());
script2.append("var ").append(e.getKey()).append(" = ")
.append("window[\"mylib_bindings_\" + ").append(seq)
.append("][\"").append(e.getKey()).append("\"];\r\n");
}
script2.append("\r\n").append(script);
return invoke(script);
} finally {
clearOnWindow(seq);
}
}
void testing() {
Bindings b = new SimpleBindings();
b.put("o", 1);
Window.alert(invoke("o", b).toString());
b.put("o", "Hello world");
Window.alert(invoke("o", b).toString());
b.put("o", 2);
Window.alert(invoke("o % 2 == 0", b).toString());
}
我们的想法是在通常可访问的对象(如窗口)上设置名称 - 值对,并更改脚本以从中获取变量。为了允许可重入的呼叫,绑定存储在不断增加的序列号下。
答案 2 :(得分:0)
new Function("o", "return (" + expressionThatUsesO + ")")(o)
如果expressionThatUsesO
是"o % 2"
,那么这相当于一个立即调用的全局函数
(function (o) { return o % 2; })(o)
供参考,https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function:
new Function ([arg1[, arg2[, ... argN]],] functionBody)
<强>参数强>
arg1, arg2, ... argN
函数用作正式参数名称的名称。每个必须是一个字符串,对应于有效的JavaScript标识符或用逗号分隔的此类字符串列表;例如
"x"
,"theValue"
或"a,b"
。
functionBody
包含包含函数定义的JavaScript语句的字符串。