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.