GWT-JSNI 在外部 JS 库中传递 JavaScriptObject

GWT-JSNI passing a JavaScriptObject in an external JS library

我拼命地尝试在 JSNI 方法中创建一个 Anno 对象,但我遇到了一个奇怪的问题:jsni 方法中的代码不起作用,但如果我在浏览器控制台中执行相同的操作, 它工作正常。

Java部分

我正在使用 JSONArray,我添加了一些 JSONObject(根据 Anno 文档,包含所有元素)。这是我的 JSNI 方法:

// I'm using the getJavaScriptObject() on my JSONArray
private static native void launch( JavaScriptObject steps )/*-{
        var anno = new $wnd.Anno(steps);
        anno.chainIndex().show();
                                                            }-*/;

浏览器部分

需要说明的是,该方法是在 onShow 事件上调用的,因此所有资源都已加载并呈现。因此,当显示元素并调用函数时,我的控制台出现此错误:

Couldn't find Anno.target 'h1'. --- anno.js:265

注意:在Anno.js中,h1是target的默认值。

但我的步骤值是正确的,当我在控制台中执行相同的命令时它起作用了:

var testAnno = new Anno([{
    content: "namespinnerFrequencyA",
    position: "center-right",
    target: ".dataAuto0"
},{
    content: "chooseFrequencyB",
    position: "top",
    target: ".dataAuto1"}]);
testAnno.show();

我不明白为什么它在一种情况下有效而在另一种情况下无效。我也尝试过使用 JSON.stringify 然后 JSON.parse 但它也不起作用。


编辑:

我想通了。在调试 anno.js 时我想到了一些事情:当我在控制台中初始化 Anno 时,本地范围看起来像这样(大图 here ):

但是当我使用 jsni 方法时,局部作用域完全不同,我的参数存储为实际数组而不是正常处理(大图 here ):

在我看来,错误消息是说找不到目标 dom 元素,而不是找不到目标 属性。当您的代码被触发时,该元素是否存在?确保它是并回复我。

问题在于 GWT 代码在 iframe 中运行(对于 sandboxing/isolation),而 Anno 仅支持来自 same 浏览上下文的数组类型。

有关问题的描述,请参阅 http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/ and http://web.mit.edu/jwalden/www/isArray.html

ECMAScript 5.1 添加了一个 Array.isArray() 函数来解决该问题并具有广泛的浏览器支持(支持 IE9):https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
jQuery 也有一个,这让(我)无法理解 Anno 不使用它而不是使用损坏的 if arg.__proto__ is Array.prototype(除非它是设计使然)。所以首先要做的事情是:在 Anno 上提交问题。

作为解决方法,应该可以使用 $wnd.Array.apply($wnd.Array, steps) 将数组从顶部复制到数组 window。