【问题标题】:GWT JSNI - Java To Javascript Back To Java Results in undefined paramsGWT JSNI - Java 到 Javascript 返回到 Java 导致未定义的参数
【发布时间】:2016-09-22 15:18:41
【问题描述】:

这两天的大部分时间里,我都在为此绞尽脑汁。我已经阅读了关于 JSNI here 的文档以及一些关于 JSNI 的不同博客文章并传递了 this one 等变量,但没有任何迹象表明我做错了什么。本质上,我想要做的是从我的 GWT 客户端类调用一个 javascript 方法,当我的类加载时我将其导出到 javascript。该方法从另一个 JS 方法获取参数并将它们存储在我传递的 Java 类的实例中。这似乎行得通。但是,一旦我在我的 java 代码中引用这些方法,它们就没有定义。我相信正在发生的事情是我的 Java Class 实例在 JS 完成后不知何故丢失了。这里有一些代码可以帮助解释工作流程...

我有一个名为 ProfileWidgee 的 Java 类。该类具有设置位置、纬度和经度的局部变量的方法。那个方法名是……

public void handleTargetPicked(String mloc, String mlat, String mlng)  {
    loc = mloc.equalsIgnoreCase("undefined") ? "" : mloc;
    lat = mlat.equalsIgnoreCase("undefined") ? "" : mlat;
    lng = mlng.equalsIgnoreCase("undefined") ? "" : mlng;
    Window.alert("setting on js side" + loc + lat + lng);
}

该方法使用名为 exportMyFunction 的 JSNI 方法作为函数导出到 JS...

public static native void exportMyFunction(ProfileWidgee instance)/*-{
   $wnd.handleTargetPicked = $entry(
      instance.@com.n.j.client.widgees.profile.ProfileWidgee::handleTargetPicked(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;));

}-*/;

这一切似乎都很好。它导出,我可以在我的 JS 中调用 handleTargetPicked,如下所示......

handleTargetPicked(encodeURIComponent(place.formatted_address), 
    encodeURIComponent(place.geometry.location.lat()),
    encodeURIComponent(place.geometry.location.lng()));

所有这些似乎都有效,并且 Window.alert() 显示正确的值。这使我相信它具有我的类的适当实例并且它正在适当地设置变量。后来,当我回到我的 Java 类时,我尝试引用这些变量,但它们总是以“未定义”的形式返回。

Window.alert("reading on the java side" + pw.getLoc() + pw.getLat() + pw.getLng());

这会导致所有三个值都为“未定义”。所以我的大问题是......是否可以从 JS 端在你的 Java 类中设置一个值,然后稍后在你的类中使用该值?

【问题讨论】:

  • 永远无法得到答案,所以我最终调用 DB 函数将值存储在数据库中,然后将它们拉到两边。

标签: javascript java gwt params jsni


【解决方案1】:

我刚刚遇到了类似的情况,碰巧看到了你的帖子。 我在任何地方都看不到任何建议的解决方案,所以尝试自己调试。

我看到的是,“this”变量指向的是 Window 而不是对象实例。

所以与其直接调用方法,例如handleTargetPicked(arg1, arg2),我使用 method.call() 传递上下文,例如handleTargetPicked.call(实例,arg1,arg2)。这种方法为我解决了这个问题。希望对您有所帮助。

【讨论】:

  • 确实是这个问题。该方法应导出为函数中的调用以获得正确的this 绑定:$entry(function(loc,lat,lng) { instance.@::handleTargetPicked(*)(loc,lat,lng); })
  • 我也被困在这个问题上,你能提供正确的签名吗?这个对吗? ` public static native void exportMyFunction(ProfileWidgee instance)/*-{ $wnd.handleTargetPicked = $entry( instance.@com.n.j.client.widgees.profile.ProfileWidgee::handleTargetPicked(Lcom/n/j/client/widgees/profile /ProfileWidgee,Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)); }-*/; `
  • 或 public static native void exportMyFunction(ProfileWidgee instance)/*-{ $wnd.handleTargetPicked = $entry( instance.@com.n.j.client.widgees.profile.ProfileWidgee::handleTargetPicked(this;Ljava /lang/String;Ljava/lang/String;Ljava/lang/String;));
  • 两者都不正确。这样做: // 假设您的方法采用 3 个字符串类型的参数 - 比如说 arg1、arg2、arg3 var methodRef = instance.@com.n.j.client.widgees.profile.ProfileWidgee::handleTargetPicked(Ljava/lang/String;Ljava /lang/String;Ljava/lang/String;); methodRef.call(this, arg1, arg2, arg3);
  • var methodRef = instance.@com.n.j.client.widgees.profile.ProfileWidgee::handleleTargetPicked(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;); methodRef.call(instance, arg1, arg2, arg3);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多