最佳实践GWT事件处理

时间:2011-09-20 11:32:01

标签: gwt event-handling

我对GWT中客户端的事件处理有疑问。

在我们的应用程序中,我们有一个非常复杂的不同模块和页面结构,它们通过客户端的gwt事件总线进行通信。现在,我的观点,事件的数量正在快速增长。例如。我打开了一个我需要的弹出窗口:

  1. 打开弹出窗口的事件
  2. 在客户端内询问某些数据的事件
  3. 获取数据并填写对话框的事件
  4. 关闭弹出窗口的事件
  5. 处理保存按钮的事件
  6. 我在EventBus实现中想到一些复杂或遗漏的东西吗?我只是希望在面对同样的问题时从社区中获得一些反馈。

1 个答案:

答案 0 :(得分:10)

对于它的价值,我有很多活动,而且还在增长。是的,我想知道我能用更少的东西做,但是当我跳过一个事件并直接链接元素时,我后悔了。

这是我昨天刚刚修好的一个例子。我有一个DataGrid小部件。我还支持使用弹出对话框重新排序列,隐藏列,重新调整列大小和着色列。单击配置按钮,显示列出的列的弹出窗口,用户可以单击复选框以显示或隐藏列,单击上移/下移按钮以重新排序列,等等。在弹出窗口中点击Apply,弹出窗口消失,DataGrid重新配置。

除此之外没有。你点击Apply然后弹出窗口只是坐在那里,用户会想知道发生了什么,DataGrid会在下面重新配置,然后弹出窗口就会消失。我们只谈了很短的时间 - 可能是一秒钟或者更多 - 但它是如此引人注目。为什么会这样?因为我懒得将popup直接绑定到configure按钮,并将Apply按钮直接绑定到DataGrid。例如,您点击了Apply,然后使用新的配置信息调用DataGrid。只有在返回的呼叫时,弹出窗口才会被拆除。

我知道这样做很糟糕,但我很懒。所以我花了20分钟我需要在我的调解器单例中写出两条消息和相关的处理程序。 DataGrid发出一条消息以启动配置对话框,弹出窗口发出一条消息来配置DataGrid。现在小部件被解耦,性能更加快速。没有“粘性”的感觉。

现在举个例子,你能否合并(1)和(2)?还有(3),(4)和(5)?当用户单击我的应用程序上的配置按钮时,该事件会携带当前配置信息(包括对发起请求的DataGrid的引用)。您可以将此信息称为“有效负载”。当用户单击弹出窗口上的“应用”按钮时,事件有效内容包括事件处理程序在处理事件时提供给目标DataGrid的所有新配置信息(包括对该原始目标DataGrid的引用)。两个事件 - 一个用于启动配置,另一个用于应用最终结果。

是的,在任何有趣的应用程序中都有大量的事件,但事件可以包含大量信息,因此我会查看您的事件组织是否过于破碎。


作为额外的一点,这是我使用的代码。我从Google的一个例子中无耻地复制了这种模式的元素。

用户可以使用菜单项寻求帮助:

@UiField
MenuItem help;

help.setCommand(new Command() {
      @Override
      public void execute() {
        BagOfState.getInstance().getCommonEventBus().fireEvent(new MenuHelpEvent());
      }
    });

对于事件(在这种情况下,当用户单击“帮助”菜单项时触发事件):

public class MenuHelpEvent extends GwtEvent<MenuHelpEvent.Handler> {

  private static final Type<Handler> TYPE = new Type<Handler>();

  public interface Handler extends EventHandler {
    void doMenuHelp();
  }

  @Override
  public GwtEvent.Type<Handler> getAssociatedType() {
    return TYPE;
  }

  @Override
  protected void dispatch(Handler handler) {
    handler.doMenuHelp();
  }

  public static HandlerRegistration register(EventBus eventBus, Handler handler) {
    return eventBus.addHandler(TYPE, handler);
  }

}

我有一个名为Mediator的单身人士,其中注册了所有事件:

MenuHelpEvent.register(BagOfState.getInstance().getCommonEventBus(),
    new MenuHelpEvent.Handler() {
      @Override
      public void doMenuHelp() {
        new MenuHelp().execute();
      }
    });

每个事件都与Command对象配合以完成工作:

public class MenuHelp implements Command {

      @Override
      public void execute() {
        new InfoMessage(BagOfState.APP_MSG.unimplementedFeatureCaption())
            .setTextAndCenter(BagOfState.APP_MSG.unimplementedFeature());
      }

    }

一切都是分离的。菜单小部件绑定到执行然后完成的命令。该命令在总线上触发事件然后完成。该事件触发Command的执行并完成。命令显示弹出帮助面板(在这种情况下,向用户显示“未实现”消息 - 是的,我很快就会知道)。与用户输入的每次交互都可以非常快速地处理并解决。它可以启动一系列事件来执行长时间的操作,但从不占用GUI来执行此操作。当然,由于元素是分离的,我可以在其他地方调用相同的元素(例如,通过按钮按钮和菜单项调用help命令)。