AutoBean, свойства массивов/списков и JSNI

Я каким-то образом борюсь с массивами и JSNI в контексте Autobeans.
В одном из моих проектов GWT я извлекаю данные из серверной части с помощью JSON.
После того, как данные получены на клиенте, я хочу визуализировать их с помощью настраиваемые виджеты визуализации (разработанные на javascript).

Вот компоненты:

Структура JSON:

{'ids':[1,2,3,4],'data':[[1.0],[1.0,2.0],[1.0,2.0,3.0] ... ]}

В основном у меня есть два набора данных в моей полезной нагрузке json. id – это массив целых чисел (int[]), а data – массив массивов с плавающей запятой (float[][]).

Конечно, есть разные способы анализа данных на клиенте. Я решил использовать AutoBeans. Итак, я определил интерфейс для своей структуры json.

Автобин:

interface MyData {
   List<Integer> ids;
   List<List<Float>> data;
}

Парсинг данных работает нормально.

Мои пользовательские виджеты визуализации имеют функцию API для установки данных, которые выглядят следующим образом:

function api_setData(ids,data) {
   //ids should be an Array of Ints
   //data should be an array of array of Floats.
}

Проблема в том, что с JSNI я не могу использовать обычные массивы Java. Я должен использовать JsArray.

public final native void setData(JsArrayInteger ids,JsArray<JsArrayInteger> data /*-{
       this.api_setData(ids,data);
    }-*/;

Поэтому мне нужно преобразовать свойства AutoBean (данные и id) в экземпляры JsArray. Есть ли лучший/приятный способ сделать это?

Или, может быть, я должен использовать JSONParser вместо AutoBeans Это более эффективно?


person Ümit    schedule 31.05.2012    source источник


Ответы (1)


Если вам приходится иметь дело с JSNI, более того, если вы используете свой MyData интерфейс только на стороне клиента, то не используйте AutoBeans. Вместо этого используйте оверлеи JSON:

public class MyData extends JavaScriptObject {
   protected MyData() { /* required for JSOs */ }

   public final native JsArrayInteger getIds() /*-{ return this.ids; }-*/;

   public final native JsArray<JsArrayNumber> getData() /*-{ return this.data; }-*/;
}

А затем для анализа вашего JSON:

MyData data = JsonUtils.safeEval(jsonStr);
customVisualizationWidget.setData(data.getIds(), data.getData());

В качестве альтернативы, предполагая, что вам нужны только проанализированные данные для setData, просто используйте JavaScriptObject.

В вашем виджете:

public final native void setData(JavaScriptObject obj) /*-{
   this.api_setData(obj.ids, obj.data);
}-*/;

Когда вам нужно разобрать JSON и передать его виджету:

customVisualizationWidget.setData(JsonUtils.safeParse(jsonStr));
person Thomas Broyer    schedule 31.05.2012
comment
Спасибо Томас за отзыв. Я подозревал, что AutoBean может не подойти для моего варианта использования. Я предполагаю, что с точки зрения производительности JSO и AutoBean должны быть одинаково быстрыми (в моем массиве данных может быть 200 тыс. значений с плавающей запятой). - person Ümit; 31.05.2012
comment
JSO всегда будут работать лучше, чем AutoBeans, потому что у AutoBeans есть оболочки вокруг JSO. Однако они являются очень продуманными обертками и создаются только по мере необходимости, поэтому, как правило, это не должно быть проблемой; но все равно. - person Thomas Broyer; 31.05.2012