如何使用 @JsInterop 在 GWT 应用程序中公开增量 DOM 库的 JS 补丁功能



我想在我的GWT应用程序中使用增量DOM库。

https://google.github.io/incremental-dom/#about

由于我来自Java世界,所以我在JavaScript命名空间和模块的概念上苦苦挣扎。我能够将闭包编译器与增量 DOM 的闭包版本一起使用(必须从源代码构建(。

它以以下行开头:

goog.module('incrementaldom');

因此,如果要在常规JS中使用它,我会键入:

var patch = goog.require('incrementaldom').patch;

然后,patch函数将在我的代码范围内可用。但是如何使其可从@JsInterop带注释的类中访问呢?

我尝试了类似的东西:

public class IncrementalDom {
  @JsMethod(namespace = "incrementaldom", name = "patch")
  public static native void patch(Element element, Patcher patcher);
  @JsFunction
  @FunctionalInterface
  public interface Patcher {
    void apply();
  }
}

但它不起作用。我在运行时收到此错误:

(TypeError) : Cannot read property 'patch' of undefined

所以我想我必须以某种方式公开incrementaldom模块或至少只公开patch方法。但我不知道怎么做。

经过一整天的战斗,我找到了解决方案。在 goog.module 中:一个 ES6 模块,类似于 goog.offer 文档的替代品,我发现缺少有关goog.scope函数角色的信息 - 所需的模块仅在作用域调用中可见。

我创建了另一个名为incrementaldom.js的闭包JS文件:

goog.provide('app.incrementaldom'); // assures creation of namespace
goog.require("incrementaldom");
goog.scope(function() {
  var module = goog.module.get("incrementaldom");
  var ns = app.incrementaldom;
  app.incrementaldom.patch = module.patch;
});
goog.exportSymbol("app.incrementaldom", app.incrementaldom);

现在我可以像这样从 Java 代码调用它:

public class IncrementalDom {
  @JsMethod(namespace = "app.incrementaldom", name = "patch")
  public static native void patch(Element element, Patcher patcher);
  @JsFunction
  @FunctionalInterface
  public interface Patcher {
    void apply();
  }
}

我仍然必须在 Closure JS 文件中单独定义在原始模块中导出的每个对象。幸运的是,我只需要patch方法。我希望有一天我会找到不那么麻烦的方式来@JsInterop goog.module :(

最新更新