我正在为 Mapbox-gl-js 构建 Jsinteropted 包装器的源对象。
我有一个抽象类Source
,它嵌入了默认方法,例如获取/设置源的类型。
@JsType(isNative = true, namespace = GLOBAL, name = JS_OBJECT_NAME)
public class Source {
@JsProperty
protected final native String getType();
@JsProperty
protected final native void setType(String type);
}
我有一些继承的类,它必须(根据 Mapbbox 文档)定义 type
属性!所以我想做这样的事情:
@JsType(isNative = true, namespace = GLOBAL, name = JS_OBJECT_NAME)
public class GeoJsonSource extends Source {
@JsConstructor
public GeoJson() {
setType("geojson");
}
}
或
@JsType(isNative = true, namespace = GLOBAL, name = JS_OBJECT_NAME)
public class GeoJsonSource extends Source {
@JsProperty
private String type = "geojson";
}
但这两者都被 GWT 编译器禁止。
现在我使用一个工厂来创建 GeoJsonSource,然后放置正确的 type
属性,但我想知道是否有 Jsinteropt 方法可以做到这一点?
最佳答案
如何为别人的类型设置默认值?你不知道。
请记住,您已经告诉编译器您只是在描述 js 类对象 - 如果有默认值,则它们已经存在。
考虑如何在 JS 中执行此操作 - 通常这只是 {type:"geojson"}
或 var obj = {}; obj.type = "geojson";
执行两个必需步骤:a) 创建一个普通对象,b) 分配默认情况下必须存在的某种类型。
工厂可以工作,也许是 GeoJsonSource 中的静态方法,这样你就可以清楚地知道你在做什么。
<小时/>另一个选择是不将 GeoJsonSource 类型标记为 native
,并且不在全局命名空间中为其指定 Object 名称(即,不允许您重写其他人的数据),如果这适合您的用例。现在,您可以控制类 - 定义默认值、在构造函数中添加逻辑等,但您必须确保正确导出方法。
这种方法的局限性包括从 JSON 字符串读取的任何对象都不会是您的 GeoJsonSource 类型(但另一方面,这可能并不重要,因为它可能已经具有 type
但其方法中仍然缺少逻辑,因为从 JSON 读取总是会创建普通的 Object 实例(除非您将 reviver
函数传递给 JSON.parse()
)。
类似地,从 JS 传递或从 JSON.parse()
读取的普通对象将无法正确通过针对非 native 类型的 instanceof
检查,这可能需要您可以在通常编写惯用 Java 的某些地方使用 Js.uncheckedCast
。
由于您正在构建一个包装器(可能会被其他人使用,他们可能不一定像您一样完全理解这些限制),所以我倾向于支持工厂方法 - 是的,它需要对您的进行更多设置侧面,但在纯 JS 中您所要求的内容更清楚,并且如果有人将纯 JS 对象视为 Java GeoJsonSource(因为它是一个),那么其行为会更可预测。
关于java - 如何为@JsProperty设置默认值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52093698/