Having gone through gwt-presenter, gwt-dispatcher, and gwt-mvp-sample,
it appears to me these projects were designed and implemented in a pre-
GWT-2.0/UiBinder age. They haven't taken into consideration the new
UiBinder features. So I am still seeking the best practice of
implementing MVP with UiBinder (using @UiHandler in particular)

The gwt-presenter approach uses Gin to inject Presenter classes, which
consequentially also inject wdigets (a presenter constructor takes a
"Display" type of argument, which is usually implemented with a
Composite subtype). Using the UiBinder approach, however, widgets are
laid out in XML files and injected via the UiBinder facility. In order
to inject corresponding presenters, one feasible solution is to
reverse the dependency of presenter and view - a view holds a
reference to a presenter. This way, when a view is injected by
UiBinder, its corresponding presenter is also created. With this
approach, a solution could be like this:

/* ------------ a presenter -------------- */
public MyPresenter implements Presenter {
      public interface Display extends IDisplay {
            HasClickHandler getAddButton();
            HasText getSomeLabel();
            // getting other "Has...Handler" and widget interfaces
      }
     private Display display;

     public MyPresenter(Display d, EventBus bus, ... ) {
           display = d;
           bus.registerEventHandler(new SomeEventHandler() { ...});
           // more ...
     }

      // inside this presenter, we also register with event bus some
      // application-level event handler
}

/* ------------ a view --------------------- */
public MyView extends Composite implements MyPresenter.Display{
    private MyPresenter presenter;
    // ...

   public MyView() {
        // eventbus is a singleton created or injected somewhere
        presenter = new MyPresenter(this, eventbus...);
        // ...
  }

  @UiHandler("somebutton")
  public void onClick(ClickEvent e) {
        presenter.getEventBus().fireEvent(new SomeEvent(...));
  }
}

/* ------------ inside MyView.ui.xml ------------- */
<ui:UiBinder ....>
     <g:SomeContainer>
          <g:Button ui:field="somebutton" text="whatever" />
     </g:SomeContainer>
</ui:UiBinder>

With the above approach, a presenter is still agnostic to any widget
and can therefore be used to conduct test against any mocked views. A
view, however, needs to strongly reference a presenter. But I think it
is fine because code in view is usually less elegant.

However, I personally don't like the above approach - I think it over-
engineers. My argument is that, with GWT 2.0 and UiBinder, MVP ought
to be simplified. Still using the above MyView example, I would like
to argue that:
(1) We don't need the "MyPresenter" class any more - cross it out
entirely
(2) MyView, now only dealing with events and leaving UI component
layouts to UiBinder, IS ACTUALLY a presenter! It should be renamed
"MyPresenter", and without implementing the "Display" interface any
more
(3) MyView.ui.xml IS the real view
(4) Inside methods annoated with "@UiHandler" in MyView.java, we just
call "eventbus.fireEvent(...)" directly and that 's it (now we should
rename "MyView.java" to "MyPresenter.java", and registers application-
level event handler within itself)

To some, this may not be a "clean enough" approach because
"MyView.java" (now renamed to "MyPresenter.java") extends Composite
widget and is not a "pure" presenter in strict sense. So I would like
to hear some discussions about the pros and cons.

Personally, I don't like the "Presenter.Display" approach where you
define a bunch of methods returning "HasClickHandler", "HasText",
"HasValue" type of things - though the presenter no longer cares about
the UI layout, it still needs to know about the component types in
that UI. How clean is such a separation?

To summarize, I would like to leverage UiBinder as View, and its
corresponding same-name java class as Presenter, and fire events
directly inside "@UiHandler" annotated methods. And that's it.

Any thoughts, anyone?

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to google-web-tool...@googlegroups.com.
To unsubscribe from this group, send email to 
google-web-toolkit+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en.

Reply via email to