如何在JsInterop中使用可能未定义的全局对象?

时间:2017-05-17 22:22:19

标签: gwt

我的第三方应用的主页可能有一个全局对象window.PageObject。如果它存在,我的应用程序需要使用其属性和功能,如果存在的话。我使用JsInterop提出了一个解决方案,但每个属性/函数需要多个方法声明:

@JsType(isNative=true, namespace=JsPackage.GLOBAL, name="PageObject")
public class PageObject {

    private PageObject PageObject() {}

    // called by every single public method
    @JsProperty(namespace=JsPackage.GLOBAL, name="PageObject")
    private static native boolean __isDefined();

    // each property has a native accessor
    @JsProperty(name="some_property")
    private static native String _getSomeProperty();

    // each property also has an overlay method that checks __isDefined()
    @JsOverlay
    public static String getSomeProperty() {
        return __isDefined() ? _getSomeProperty() : null;
    }

    // calling a function safely requires an additional check to see if it exists
    @JsProperty(name="some_procedure")
    private static boolean _hasSomeProcedure();

    @JsMethod(name="some_procedure")
    private static native void _someProcedure();

    @JsOverlay
    public static void someProcedure() {
        if (__isDefined() && _hasSomeProcedure()) {
            _someProcedure();
        }
    }

}

我是否遗漏了JsInterop中更好地处理这个问题的部分内容?是否有其他解决方案更易于使用(不包括JSNI)?

2 个答案:

答案 0 :(得分:2)

如何使用PageObject实例?

创建一个静态getter来检索实例,然后在调用方法之前检查null(就像你在JS中做的那样)。

现在,如果你真的想要一些静态API,当没有定义对象时,它们是no-op / return null,那么你就没有多少选择,无论如何都需要编写一个包装器(就像你一样)在JS中做)

答案 1 :(得分:0)

要检查window.PageObject的存在,可以执行以下操作:

  1. 为JavaScript变量“窗口”创建JsInterop包装器

    @JsType(isNative=true, namespace=JsPackage.GLOBAL, name="window")
    public class JsWindowWrapper {
        public static Object PageObject;
    }
    
  2. 检查是否定义了window.PageObject

    if (null != JsWindowWrapper.PageObject) { ... };