Как установить значение по умолчанию для @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 (потому что он один).

Другие вопросы по тегам