将值绑定到脚本中提到的变量

发布于 2024-12-08 21:41:25 字数 405 浏览 0 评论 0原文

我正在创建一个 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”?

I'm creating a GWT version of a Java library which has support for the javax.script.ScriptEngine to evaluate functions dynamically via Javascript, e.g.,

o => o % 2 == 0

where at runtime, the value of "o" is defined via the javax.script.Bindings (the o => part is stripped of course).

The problem is, how can I get the same effect from within GWT? I use a native function

native Object nativeEval(String script) /*-{
    return $wnd.eval(script);
}-*/

nativeEval("o % 2 == 0");

But how can I bind a value to the identifier "o"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

南烟 2024-12-15 21:41:25
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”

函数体

包含构成函数定义的 JavaScript 语句的字符串。

new Function("o", "return (" + expressionThatUsesO + ")")(o)

If expressionThatUsesO is "o % 2" then this is equivalent to a global function that is immediately called

(function (o) { return o % 2; })(o)

For reference, https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function :

new Function ([arg1[, arg2[, ... argN]],] functionBody)

Parameters

arg1, arg2, ... argN

Names to be used by the function as formal argument names. Each must be a string that corresponds to a valid JavaScript identifier or a list of such strings separated with a comma; for example "x", "theValue", or "a,b".

functionBody

A string containing the JavaScript statements comprising the function definition.

多彩岁月 2024-12-15 21:41:25

将值传递给标识符“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)+"");

To pass values to the identifier "o" :

public native void define(String handle, Object o) /*-{
    eval("var " + handle+ "="+ o);
}-*/;
public native boolean nativeEval(String script) /*-{
    return eval(script);
}-*/;

And then calling it :

String script = "o % 2 == 0";
define("o",2);
Window.alert(nativeEval(script)+"");
define("o",3);
Window.alert(nativeEval(script)+"");
清醇 2024-12-15 21:41:25

我想我找到了一个解决方案:

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());
}

这个想法是在一个通常可访问的对象(例如窗口)上设置名称-值对,并更改脚本以从中获取变量。为了允许可重入的调用,绑定存储在不断增加的序列号下。

I guess I found a solution:

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());
}

The idea is to set the name-value pairs on a commonly accessible object, such as window and alter the script to get the variables from it. In order to allow a re-entrant capable call, the bindings are stored under a constantly increasing sequence number.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文