I am using JSNI to pass some parameters to the GWT app, so far I have managed to pass a simple String array (JsArrayString) but I would like to pass an associative array though and don't know how to extract the data with the keys (I've managed to pass the array on to the GWT app but can't parse it), like this:

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")
}

I've found a topic that does the opposite of what I am trying to do, but can't figure out how to do this.

有帮助吗?

解决方案

There's nothing like an "associative array" in JS; what you're talking about is an object. JsArrayString represents a JS array that you expect to contain only strings. JS objects are represented as JavaScriptObjects in GWT, and there's no built-in easy way to dynamically access their properties.

If you know what properties you need to access, you'd better create a JavaScriptObject subclass, also known as an overlay type:

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();
}

If you don't know what properties the object will have and want to discover them dynamically, then you can wrap a JavaScriptObject into a com.google.gwt.json.client.JSONObject, but it's less readable and creates spurious short-lived objects:

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();
}

OK, I lied, there's an easy built-in way, but it's experimental (and possibly broken), and is designed to work only in modern browsers (i.e. not IE 9 and below, possibly not Opera 12 and below): you can use elemental.js.util.JsMapFromStringTo and similar classes.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top