【问题标题】:How do I assign a JSONObject or JavaScriptObject to $wnd[x] in GWT?如何在 GWT 中将 JSONObject 或 JavaScriptObject 分配给 $wnd[x]?
【发布时间】:2012-07-08 22:05:00
【问题描述】:

我使用 GWT 字典从我的 HTML 页面中读取了一些 varvar 看起来像这样:

var test = {
    "a" : "123",
    "b" : "jg34l",
    ...
}

现在我通过 AJAX-Call 为我的 JS var 获取新内容。目前我这样覆盖它:

public native void set(String key, String value) /*-{
    $wnd["test"][key] = value;
}-*/;

public void onResponseReceived(Request request, Response response) {
    JSONObject obj = (JSONObject) JSONParser.parseLenient(response.getText());

    for (String key : obj.keySet()) {
        JSONString val = (JSONString) obj.get(key);
        set(key, val.stringValue());
    }
}

如您所见,我得到了一个 JSON 字符串。解析它。将其转换为 JSONObject。获取每个键值对并使用 JSNI 方法设置对。

一定有更简单的方法来做到这一点?!我只想说:$wnd["test"] = myJsonObject

请帮助我,因为这是性能关键步骤(最多 1000 个键值对)。

【问题讨论】:

    标签: javascript json gwt jsni


    【解决方案1】:

    您可以尝试使用JSO(应该也比JSONObject快得多)
    像这样的:

    public native void set(JavaScriptObject data) /*-{
       $wnd['test'] = data;
    }-*/;
    
    public void onResponseReceived(Request request, Response response) {
        JavascriptObject data = JsonUtils.safeEval(response.getText()).case();
        set(data);
    }
    

    我自己没有试过,所以我不能说 100% 有效。

    更新
    您可以直接返回支持类似哈希访问的JavaScriptObject,而不是字典:

    public class MyDictionary extends JavaScriptObject {
    
        public native String get(String name) /*-{
            return this[name];
        }-*/;
    }
    
    public native MyDictionary getData() /*-{
       return $wnd['test'];
    }-*/
    

    【讨论】:

    • 是的,这行得通,谢谢。但它与 GWT 字典有问题:( 字典不承认,有新的价值。用我上面的方法它有效。我想我必须以某种方式“重新加载”字典。
    • “字典不承认有新值”是什么意思?顺便提一句。您还可以将 JSO 与字典一起使用。
    • 问题是:例如在我的 HTML 文件中:var test = {...}。然后我使用Dictionary dict = Dictionary.getDictionary("test") 来获取test 的内容。然后尝试使用$wnd['test'] = jso;test 的内容替换为JavaScriptObject jso。现在:dict.get("key") 返回旧值,但:alert($wnd['test']['key']) 返回新值。如果我使用上面帖子中的方法替换test 的内容,则一切正常。请参阅下面我的帖子以获取解决方案(很简单:不要覆盖$wnd['test'],而是创建一个新的var 并使用它。)
    • 您说:“顺便说一句。您还可以将 JSO 与字典一起使用。”。你的意思是可以说像Dictionary dict = Dictionary.getDictionary(JavaScriptObject jso) 这样的话吗?你有例子吗?
    • 我猜当您调用Dictionary dict = Dictionary.getDictionary("test") 时,它会创建一个副本,因此如果您通过本机final 方法更新主机页面中的javascript 值,dict 实例仍保留旧信息。您可以创建一个自定义的JavascriptObject,而不是字典,它支持类似哈希的访问。 (有关详细信息,请参阅我的更新答案)。
    【解决方案2】:

    这是我的 GWT Dictionary 版本(真正的动态语言切换):

    public native void setTranslation(String locale, JavaScriptObject translationData) /*-{
        $wnd[locale] = translationData;
    }-*/
    
    @Inject
    TranslationProvider translationProvider;
    
    public void onResponseReceived(Request request, Response response) {
        String newLocale = "en";
        JavaScriptObject translationData = JsonUtils.unsafeEval(response);
        setTranslation(newLocale, translationData);
        translationProvider.setLocale(newLocale);
        LocaleChangeEvent.fire(eventBus);
    }
    

    每个显示可翻译文本的 Widget 都注册到 LocaleChangeEvent 并实现 LocaleChangeEventHandler

    public interface LocaleChangeEventHandler extends EventHandler {
        void onLocaleChange(LocaleChangeEvent event);
    }
    

    onLocaleChange 方法中,它只是从TranslationProvider 类中调用get(...) 方法来接收它的字符串:

    public class LocaleAwareLabel extends Label implements LocaleChangeEventHandler {
        TranslationProvider translationProvider;
    
        @Inject
        public LocaleAwareLabel(TranslationProvider translationProvider, EventBus eventBus) {
            this.translationProvider = translationProvider;
            eventBus.addHandler(LocaleChangeEvent.TYPE, this);
            get();
        }
    
        public void get() {
            this.setText(translationProvider.get("myDictionaryKey"));
        }
    
        @Override
        public void onLocaleChange(LocaleChangeEvent event) {
            get();
        }
    }
    

    这里是TranslationProvider 类:

    @Singleton
    public class TranslationProvider {
        Dictionary dictionary;
    
        public void setActiveLocale(String locale) {
            dictionary = Dictionary.getDictionary(locale);
        }
    
        public String get(String key) {
            dictionary.get(key);
        }
    }
    

    就是这样!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-24
      • 1970-01-01
      • 1970-01-01
      • 2019-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多