繁体   English   中英

JSNI脚本失败,但在Chrome Devtools控制台中运行时脚本成功

[英]JSNI script fails, but script succeeds when ran in Chrome Devtools console

我正在努力通过JSNI使用测试数据来利用名为cytoscape.js的外部JavaScript库。 当我按我的Java类的要求运行脚本时,它无法生成图形。 但是,当我通过Chrome Devtools控制台运行它时,它可以正常工作。

所有的值看似正确地传递到cytoscape.js库。 当前,JSNI代码未通过控制台库能够通过的Javascript库执行的测试。

这是我正在使用的JSNI代码:

public static native void cytoscape() /*-{
        var cy = $wnd.cy = $wnd.cytoscape({container: $wnd.document.getElementById('cy'),
            elements: $wnd.glyElements, 
            style: [ { selector: 'node', style: { 'background-color': '#666', 'label': 'data(id)' } }, 
                { selector: 'edge', style: { 'width': 3, 'line-color': '#ccc', 'target-arrow-color': '#ccc', 'target-arrow-shape': 'triangle' } } ],
            layout: { name: 'grid', rows: 1 } });
    }-*/;

“ $ wnd”。 用于获取正确的范围。

这是控制台代码:

var cy = window.cy = cytoscape({ 
            container: document.getElementById('cy'),
            elements: glyElements, 
            style: [ { selector: 'node', style: { 'background-color': '#666', 'label': 'data(id)' } }, { selector: 'edge', style: { 'width': 3, 'line-color': '#ccc', 'target-arrow-color': '#ccc', 'target-arrow-shape': 'triangle' } } ], 
            layout: { name: 'grid', rows: 1 } 
        });

我在两种情况下使用的元素都存储在.js文件中,并且我确保在两种情况下都可以访问它们。 就像我提到的那样,Devtools调试向我展示了正确的值已传递到cytoscape.js库中。

JSNI代码使cytoscape.js库中的以下return语句失败:

var plainObject = function plainObject(obj) {
    return obj != null && _typeof(obj) === typeofobj && !array(obj) && obj.constructor === Object;
  };

如果我注释掉“ && obj.constructor ===对象;” 在cytoscape.js的第145行上,代码使用我的JSNI脚本正确运行。 这使我相信通过JSNI和控制台创建cytoscape对象的方式有所不同。 尽管如此,Dev工具仍将控制台和JSNI方法列为提供相同的对象。 如何更新我的JSNI代码以使其符合此检查要求?

理想情况下,在这种情况下,JSNI应该可用。 我不确定为什么通过JSNI传递值会导致此if语句在通过控制台运行时失败,而通过if语句。

问题在于Object与Object不完全相同,检查instanceof几乎可以肯定比cytoscape的作者所认为的要多得多-JS难道不是吗?

cytoscape.js项目的instanceof Object测试不仅是针对“这是一个普通的Object,还是其他类型的实例”的测试,而是实际上测试“这是我的 Window实例中Object类的实例,并且而不是来自其他任何iframe /窗口”。

GWT的默认链接器会在iframe中评估您的代码,以防止意外泄漏全局变量并使加载到同一页面的JS混乱,或使同一页面上的其他JS覆盖或以其他方式干扰GWT的代码。

除了尝试将cytoscape的代码更正为不太僵化和不灵活的方式以外,还有几种方法可以解决此问题。

  • 从外部页面创建Object的实例:为此,您必须直接创建对象,而不是使用{...}语法,该语法默认为您恰巧在其中执行的任何窗口。
       public static native void cytoscape() /*-{
           var obj = new $wnd.Object();
           obj.container = $wnd.document.getElementById('cy');//can also be simply $doc.getElementById('cy')
           obj.elements = $wnd.glyElements;
           // Note that you may have to repeat this for each of these nested objects, depending
           // on how picky the library is being on otherwise identically structured code...
           obj.style = [ { selector: 'node', style: { 'background-color': '#666', 'label': 'data(id)' } }, 
                   { selector: 'edge', style: { 'width': 3, 'line-color': '#ccc', 'target-arrow-color': '#ccc',
   'target-arrow-shape': 'triangle' } } ];
           obj.layout = { name: 'grid', rows: 1 };
           var cy = $wnd.cy = $wnd.cytoscape(obj);
       }-*/; 
  • 在执行GWT代码的情况下,将cytoscape.js加载到同一iframe中。请注意,它可能在那里实际上不起作用,这会导致其他问题,但是您可以尝试使用ScriptInjector将脚本内容插入GWT应用程序中,而不用引用它直接在您的.html页面中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM