Как установить значение по умолчанию для @JsProperty?
Я создаю оболочку Jsinteropted для исходных объектов Mapbox-gl-js.
У меня абстрактный класс 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 сделать это?
1 ответ
Как установить значение по умолчанию для чужого типа? Вы не
Помните, вы сказали компилятору, что вы просто описываете класс js Object - если есть значения по умолчанию, они уже существуют.
Подумайте, как бы вы сделали это в JS - обычно это просто {type:"geojson"}
или же var obj = {}; obj.type = "geojson";
чтобы выполнить два необходимых шага: а) создание простого объекта и б) назначение некоторого типа, который должен быть там по умолчанию.
Фабрика будет работать, возможно, статический метод в GeoJsonSource, чтобы было понятно, что вы делаете.
Другой вариант - не отмечать тип GeoJsonSource как native
и не присваивайте ему имя Object в глобальном пространстве имен (т. е. вам не разрешено переписывать чужие данные), если это подходит для вашего варианта использования. Теперь это позволит вам управлять классом - определять значения по умолчанию, добавлять логику в конструкторы и тому подобное, но вы должны убедиться, что методы экспортируются правильно.
Ограничения этого подхода включают в себя тот факт, что любой объект, считываемый из строки JSON, не будет вашим типом GeoJsonSource (но, с другой стороны, это может не иметь значения, поскольку он, вероятно, уже имеет type
имущество. Логика все равно будет отсутствовать в его методах, поскольку чтение из JSON всегда создает простые экземпляры объекта (если вы не передадите reviver
функция к JSON.parse()
).
Аналогично, простой Объект передается из JS или читается из JSON.parse()
не будет правильно пройти instanceof
проверьте свой не родной тип, который может потребовать от вас использования Js.uncheckedCast
в некоторых местах, где вы обычно пишете идиоматическую Java.
Поскольку вы создаете оболочку (которая может использоваться другими, которые не обязательно понимают эти ограничения так же полно, как вы), я бы предпочел заводской подход - да, он требует немного больше настроек на вашей стороне, но в простом JS он понятнее того, о чем вы просите, и будет вести себя более предсказуемо, если кто-то рассматривает простой JS-объект как Java GeoJsonSource (потому что он один).