GWT: анализ ассоциативного массива JavaScript с использованием JSNI JsArrayString

Я использую JSNI для передачи некоторых параметров в приложение GWT, до сих пор мне удалось передать простой массив строк (JsArrayString), но я хотел бы передать ассоциативный массив и не знаю, как извлечь данные с ключами (Мне удалось передать массив в приложение GWT, но я не могу его проанализировать), например:

public static native void exportFunction() /*-{
    $wnd.myFunction = 
        $entry(@com.mypackage.client.HelloWorld::helloWorld(Lcom/google/gwt/core/client/JsArrayString;));
}-*/;    

var associative = { "hello" : "world", "goodbye" : "world" };
window.myFunction(associative);

public static void helloWorld(JsArrayString strings) {
    // String value = strings.get("hello")
}

Я нашел тему, которая делает противоположное тому, что я пытаюсь сделать, но может не пойму как это сделать.


person enp4yne    schedule 02.07.2013    source источник


Ответы (1)


В JS нет ничего похожего на «ассоциативный массив»; вы говорите об объекте. JsArrayString представляет массив JS, который, как вы ожидаете, будет содержать только строки. Объекты JS представлены как JavaScriptObjects в GWT, и нет встроенного простого способа динамического доступа к их свойствам.

Если вы знаете, к каким свойствам вам нужен доступ, вам лучше создать подкласс JavaScriptObject, также известный как тип наложения:

public class MyObj extends JavaScriptObject {
  protected MyObj() { /* required by GWT */ }

  public final native String getHello() /*-{ return this.hello }-*/;
  public final native String getGoodbye() /*-{ return this.goodbye }-*/;
}

…

public static void helloWorld(MyObj strings) {
  String value = strings.getHello();
}

Если вы не знаете, какими свойствами будет обладать объект, и хотите обнаружить их динамически, вы можете обернуть JavaScriptObject в com.google.gwt.json.client.JSONObject, но это менее читабельно и создает ложные недолговечные объекты:

public static void helloWorld(JavaScriptObject strings) {
  JSONObject o = new JSONObject(strings);
  // Beware: will throw if there's no "hello" property in the object
  String value = o.get("hello").isString().stringValue();
}

Хорошо, я соврал, есть простой встроенный способ, но он экспериментальный (и, возможно, сломанный) и предназначен для работы только в современных браузерах (т.е. не в IE 9 и ниже, возможно, не в Opera 12 и ниже): вы можете использовать elemental.js.util.JsMapFromStringTo и подобные классы.

person Thomas Broyer    schedule 02.07.2013
comment
именно то, что мне было нужно! Я знаю, к каким свойствам мне нужно получить доступ, поэтому первое решение сработало отлично :) спасибо! - person enp4yne; 02.07.2013