GWT 中的 Javascript 模块功能与 JsInterop

问题描述 投票:0回答:2

希望这比我做的要容易得多 - 我是一名 Java 程序员,一些内部 Javascript 方面对我来说有点陌生。

尝试将出色的 CodeJar 库嵌入到 GWT 面板中。 CodeJar 有一个非常漂亮/简单的示例:

<script type="module">
  import {CodeJar} from './codejar.js'
  import {withLineNumbers} from './linenumbers.js';

  const editor = document.querySelector('.editor')

  const highlight = editor => {
    // highlight.js does not trim old tags,
    // let's do it by this hack.
    editor.textContent = editor.textContent
    hljs.highlightBlock(editor)
  }

  const jar = CodeJar(editor, withLineNumbers(highlight), {
    indentOn: /[(\[{]$/
  })

  jar.updateCode(localStorage.getItem('code'))
  jar.onUpdate(code => {
    localStorage.setItem('code', code)
  })
</script>

模块函数本身如下所示:

export function CodeJar(editor, highlight, opt = {}) { ... }

'editor'是一个Div引用,'highlight'是一个回调库函数,用于处理代码高亮。

我正在处理的是 JsInterop 标记和代码,以使 Javascript 模块与 GWT 一起工作。以上有几个方面是我正在努力解决的

  • 替换“导入”,以便 javascript 模块代码可用于 GWT。显然,我可以将 js 导入到我的顶级 index.html 中,但据我了解,JS 模块不会成为全局命名空间的一部分,它们只能从导入它们的 JS 模块中使用。就我而言,可能需要是 GWT 代码。
  • 在GWT中重新编码上述内容时如何传入回调函数
  • 如何获取我自己的“jar”引用来执行自己的文本设置/获取(取代使用本地存储)
gwt gwt-jsinterop
2个回答
3
投票

要加载脚本并使其可用于 GWT 使用,您(至少)有 3 种可能性:

  • import
    中使用静态
    <script type=module>
    ,然后将
    CodeJar
    函数分配给
    window
    属性以使其全局可用(实际上可能是另一个 window 对象)
    使用 GWT 中的动态 
  • import()
  • ,使用 JsInterop 和可能的 elemental2-promise
    使用 Rollup/Webpack/whatever 将 CodeJar 模块变成非模块脚本,这样你就可以以不同的方式使用它
  • 接下来,您需要创建 JsInterop 绑定,以便可以从 GWT 调用它;类似的东西(假设您将 CodeJar 作为
  • window.CodeJar
全局可用,并使用 elemental2-dom 作为

HTMLElement

,但 
com.google.gwt.dom.client.Element
 也可以工作):
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "?")
interface CodeJar {
  @JsMethod(namespace = JsPackage.GLOBAL, name = "CodeJar")
  static native CodeJar newInstance(HTMLElement element, HighlightFn highlight);
  @JsMethod(namespace = JsPackage.GLOBAL, name = "CodeJar")
  static native CodeJar newInstance(HTMLElement element, HighlightFn highlight, Options opts);

  void updateOptions(Options options);
  void updateCode(String code);
  void onUpdate(UpdateFn cb);
  void destroy();
}

@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
class Options {
  public String tab;
  public JsRegExp indentOn;
  public boolean spellcheck;
  public boolean addClosing;
}

@JsFunction
@FunctionalInterface
interface HighlightFn {
  void highlight(HTMLElement e);
}

@JsFunction
@FunctionalInterface
interface UpdateFn {
  void onUpdate(String code);
}

使用上面的代码,您应该能够使用以下内容创建编辑器:
CodeJar jar = CodeJar.newInstance(editor, MyHighlighter::highlight);

如果您使用动态
import()
,请将静态方法替换为

@JsType

 接口中代表从 Promise 接收的模块的实例方法。

@Thomas 有机会扩展如何使用 JsInterop 实现动态 import() 吗?

0
投票

© www.soinside.com 2019 - 2024. All rights reserved.