Yuh*_*hao 3 javascript java arrays gwt
我有一个String数组,现在我想将它传递给JSNI函数.我尝试JsArrayString在GWT中使用,但是我发现它无法直接初始化,因为它没有可见的构造函数.那么如何将我的String数组传递给JSNI函数并在我的javascript代码中使用它?代码如下所示:
public void callJSNI() {
String[] stringArray = xxx;
//How should I convert the array into a JSNI-readable format here?
}
private native void JSNIMethod(JsArrayString array) /*-{
//some code to use the array in javascript
}-*/
Run Code Online (Sandbox Code Playgroud)
API不提供简单的方法,您必须创建一个实用程序方法,该方法将:
像这样的东西:
public static JsArrayString toJsArray(String[] input) {
JsArrayString jsArrayString = createEmptyJsArrayString();
for (String s : input) {
jsArrayString.push(s);
}
return jsArrayString;
}
private static native JsArrayString createEmptyJsArrayString() /*-{
return [];
}-*/;
Run Code Online (Sandbox Code Playgroud)
正如OP建议的那样,我们当然可以跳过本机初始化和使用JsArrayString.createArray().
现在我们可以摆脱本机初始化,所以我们的代码简化为:
public static JsArrayString toJsArray(String[] input) {
JsArrayString jsArrayString = JsArrayString.createArray().cast();
for (String s : input) {
jsArrayString.push(s);
}
return jsArrayString;
}
Run Code Online (Sandbox Code Playgroud)
Eliran Malka的答案是一个很好的起点.但请注意,在某些情况下,存在一种更有效的扩展解决方案.这就是我创造另一个答案的原因.
简单的解决方案是:
public static JsArrayString toJsArray(String[] input) {
JsArrayString jsArrayString = JsArrayString.createArray().cast();
for (String s : input) {
jsArrayString.push(s);
}
return jsArrayString;
}
Run Code Online (Sandbox Code Playgroud)
扩展/更高效的解决方案需要一些背景知识......
当Java代码使用Java数组时,GWT编译器使用JS数组.所以在这种情况下你已经有了一个JS数组.但这可能导致副作用,导致Dev和Prod模式中的不同行为:
由于我们在Dev模式下拥有真正的Java数组,因此始终需要通过复制值来转换为JS数组.其中一个阵列中的操作对另一个阵列不可见.
在Prod模式下,如果我们直接使用Java数组作为JS数组,我们只会有一个数组.因此,Java或JS代码中的操作会影响另一个世界.
但是,如果以下内容适用于您的用例,则可以使用该数组而无需创建另一个数组:
在这种情况下,您将不会有副作用(Dev和Prod模式中的不同行为),并且数组可以直接在本机代码中使用.
这种实现包含在GWT的JsArrayUtils中.但不幸的是,目前没有String数组的实现.但实现将如下所示:
public static JsArrayString readOnlyJsArray(String[] array) {
if (GWT.isScript()) {
return arrayAsJsArrayForProdMode(array).cast();
}
JsArrayString dest = JsArrayString.createArray().cast();
for (int i = 0; i < array.length; ++i) {
dest.push(array[i]);
}
return dest;
}
private static native JavaScriptObject arrayAsJsArrayForProdMode(Object array) /*-{
return array;
}-*/;
Run Code Online (Sandbox Code Playgroud)