GWT MVP:HandlerManager EventHandler与GUI EventHandler

时间:2014-08-09 08:51:30

标签: java events gwt gwt-mvp

我正在使用GWT MVP开发一个应用程序。我看到我们可以在GWT MVP代码中有两种事件处理程序,但我不太确定我应该在哪个地方使用哪种:

1)EditEventHandler中的HandlerManager(eventBus)EventHandlers(例如下面的AppController):

eventBus.addHandler(EditEvent.TYPE,
      new EditEventHandler() {
        public void onEdit(EditEvent event) {
          doEdit(event.getId()); // this would open a new screen, call AsyncService etc
        }
      });

据我所知,这些事件处理程序用于处理应用程序范围的自定义事件。

2)ClickHandler中的GUI / View事件处理程序(例如Presenter),我处理GUI事件,然后触发应用程序事件以调用其处理程序,如下所示:

display.getList().addClickHandler(new ClickHandler() {
    public void onClick(ClickEvent event) {
      int selectedRow = display.getClickedRow(event);

      if (selectedRow >= 0) {
        String id = myDetails.get(selectedRow).getId();
        eventBus.fireEvent(new EditEvent(id)); // this in turn would invoke the EditEventHandler above
      }
    }
  });

现在,我的问题是:

1)为什么我们需要为应用程序事件(例如EditEvent)编写EventHandler,而不是直接在关联的GUI事件处理程序中添加该代码(例如addClickHandler)?

2)我们不能编写用于打开新屏幕的代码,直接在GUI EventHandler方法中调用AsyncService等,例如onClick

3)这不会使你的代码更具可读性,因为触发的事件和需要完成的工作都在一个地方,即Presenter,你不必返回在您的Presenter代码和AppController代码之间?

1 个答案:

答案 0 :(得分:1)

  1. 你可以这样做,在一个小应用程序中,这可能是正确的方法。但是,您肯定会增加GUI,业务逻辑和各种组件之间的耦合。您应该将屏幕设想为独立单元,并避免这些单元之间的任何耦合。在最好的情况下,显示记录列表的屏幕应该对其他屏幕或任何其他组件一无所知。它应该只关心那些记录。
  2. 从技术上讲,没有理由不能在GUI EventHandler中调用AsyncService。只需确保您在Presenter而不是View中执行此操作。然而,您的应用程序越复杂,这种方法可能会变得更加混乱。您将在各种Presenters中散布许多AsyncService调用。在AppController中对它们进行分组可能是一种更好的方法,因此有一个地方需要查找,以及2.)您可以轻松测试/模拟AsyncService中的所有AppController次来电}。
  3. 也可以在Presenter内完成工作,而无需经过AppController并返回。但是,将AsyncService调用放入AppController仍然有意义,因为您可能需要执行一些操作(例如在LocalStroage中缓存结果,提交其他事件等)和/或通知其他屏幕/组件有关加载的数据。
  4. 将事件视为消息。这是一个例子:
    您有一个View / Presenter对用于显示记录列表(即RecordListPresenter)。用户单击其中一个记录上的编辑按钮,您有一个单独的View / Presenter对用于编辑特定记录(即RecordEditPresenter)。您可以RecordListPresenter发送消息来编辑记录(RecordEditPresenter,而不是从您的RecordListPresenterEdit的引用,这会使他们相互了解并增加耦合。事件)。 AppController将充当Mediator并打开加载数据并打开RecordEditEditor(它也可以仅使用加载的数据触发事件,RecordEditEditor可以显示自身)。
    但是现在想象你还有一个HeaderPresenter用于显示一些面包屑信息(就像它正在编辑哪个记录)。如果您采用“无事件”方法,则需要RecordListPresenterRecordEditPresenter中的其他引用来驱动它。 Events Presenters HeaderPresenter不必知道有{{1}}。他们只是发动事件。

    现在,在一个复杂的应用程序中,您可能拥有许多独立单元。