GWT:在启动时进行初始RPC调用的最佳方法?

时间:2011-10-27 14:28:01

标签: gwt rpc

使用GWT在启动时执行初始RPC调用的最佳方法是什么?

我想检索用户加载页面时在服务器端动态生成的配置数据。但是如果我从浏览器进行异步RPC调用以检索数据,我有时在页面完全加载之前没有得到响应,导致页面无法访问该配置数据。 (例如没有Thread.sleep()函数)

感谢


感谢@ Steve-J的回复,我找到了解决方案......

基本上这个想法如下:

  • 创建一个新的StartupCompleted事件
  • 在onModuleLoad()
  • 中启动初始RPC调用
  • 在该RPC调用的onSucess方法中,触发StartupCompleted事件
  • 在App Controller的go()方法的末尾,而不是在History [with History.newItem(“default”)中插入默认操作; ],或者通过书签[使用History.fireCurrentHistoryState();来触发当前的History状态; ],什么都不做
  • 在eventbus上为新的StartupCompleted事件注册处理程序
  • 触发StartupCompleted事件时,抓住它并在那时,在历史记录中插入默认操作或触发当前历史记录状态

et voila ...

在执行任何其他操作之前,初始RPC调用已完成...

这种方法有什么问题吗?

请注意,正如@ Tom-Miette建议的那样,在收到StartupCompleted事件之前,有一条简单的“loading ...”消息是很好的。

4 个答案:

答案 0 :(得分:3)

不确定它是否是最佳方式,但一个好方法是完全避免初始调用,并使用jsp页面而不是html页面作为应用程序的入口点。然后,您可以在页面服务器端的javascript中为初始状态设置变量,例如

<script type="text/javascript">
    var InitialState = {
    "userName" : "<%= userName %>",
    "emailAddress" : "<%= emailAddress %>",
    etc...
};

在GWT应用程序中,您可以使用GWT Dictionary类

读取这些值
Dictionary state = Dictionary.getDictionary("InitialState");
String userName = state.get("userName");
String emailAddress = state.get("emailAddress");

答案 1 :(得分:3)

您是否正在使用消息传递来控制流量?我执行RPC调用,并且成功时,我发送消息,触发用户与之交互的第一个活动弹出窗口。失败时,会触发一条不同的消息,触发弹出窗口告诉用户他无法继续。

不要忘记在弹出窗口中启用玻璃面板,以便用户在等待时不会弄乱背景中的任何内容。

更新: 来自评论:“但我的问题是,用户可以为网页添加书签,直接转到该网页,无需任何互动。我可以最终我没有收到RPC调用的结果,但是我正在生成他请求的页面。即使在那一代我尝试检查我是否收到了结果,我无法暂停直到完成页面生成之前的情况。“

啊,我明白了。好的,GWT有一个解决方案。你应该看看Activities and Places。当用户为“页面”添加书签时,他实际上正在为GWT应用程序的状态添加书签。当他返回到那个“页面”时,Activity被触发并自动调用start()方法。这是您从服务器检索数据并执行所需的任何其他设置的机会。获得数据后,start()方法将继续设置所谓的“视图”。从用户的角度来看,“页面”已经“加载”。

答案 2 :(得分:0)

用一种“加载屏幕”覆盖你的html页面:

<div 
id="loading"
style="
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  background: black;
  color: white;"
>
  Loading...
</div>

并在RPC成功/失败时删除它:

RootPanel.get("loading").getElement().removeFromParent();

答案 3 :(得分:0)

FWIW我有一个解决方案,涉及暂停 EntryPoint.onModuleLoad()直到RPC返回。

我正在使用依赖注入 GWTP Dispatch 这种复杂的引导过程。我还希望结果在我的系统(客户端)中成为单例实例

结果是GWT本机(无命令模式)RPC调用,在成功时启动依赖注入。

EntryPoint class snippet:

@Override
public void onModuleLoad() {
    SessionInfoProvider.init(new Runnable() {
        @Override
        public void run() {
            // can now complete setup
            AppInjector injector = GWT.create(AppInjector.class);
            injector.bootstrap();
        }
    });
}

SessionInfoProvider摘录:

public class SessionInfoProvider implements Provider<SessionInfo> {
private static SessionInfo.Bean sessionInfo;

/**
 * Needs to be called before the module is used.
 */
public static void init(final Runnable onCompletion) {
    GreetingServiceAsync s = GWT.create(GreetingService.class);
    s.loadSessionInfo(new AsyncCallback<SessionInfo.Bean>() {
        @Override
        public void onFailure(Throwable caught) {
            GWT.log("Failed to retrieve Session Info");
        }

        @Override
        public void onSuccess(SessionInfo.Bean result) {
            GWT.log("Successfully retrieved session info bean.  Username:" + result.getUserName());
            sessionInfo = result;
            onCompletion.run();
        }
    });
}

@Override
public SessionInfo get() {
    if (sessionInfo == null) throw illegalState("Session Info not ready.");
    return sessionInfo;
}
}