I am using GWT MVP to develop an application. I saw we can have two kinds of event handlers in GWT MVP code, but I am not very sure about which kind should I use in which place:
1) HandlerManager (eventBus) EventHandlers (e.g. EditEventHandler below) in AppController:
eventBus.addHandler(EditEvent.TYPE,
new EditEventHandler() {
public void onEdit(EditEvent event) {
doEdit(event.getId()); // this would open a new screen, call AsyncService etc
}
});
I understand, these kind of event handlers are used for handling application-wide custom events.
2) GUI/View Event Handlers (e.g. ClickHandler) in Presenter, where I handle the GUI event and then fire the application event to invoke its handler as below:
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
}
}
});
Now, my questions are:
1) Why do we need to write EventHandler for application events (e.g. EditEvent), and not add that code directly in the associated GUI event handler (e.g. addClickHandler)?
2)Can't we write the code for opening new screen, calling AsyncService etc directly in GUI EventHandler method, such as onClick ?
3) Wouldn't that make your code more readable, as the event that is triggered and the work that needs to be done is all in one place i.e.Presenter and you don't have to go back and forth between your Presenter code and AppController code?
AsyncServicein your GUI EventHandler. Just make sure you do it in yourPresenterand not in yourView. However the more complex your app gets the messier this approach might get. You will have many AsyncService calls sprinkled all over your variousPresenters. It might be a better approach to group them in yourAppControllerso there is 1.) one place to look for and 2.) you can easily test/mock allAsyncServicecalls in yourAppController.Presentershould also be done there without needing to go throughAppControllerand back. However it still might make sense to put theAsyncServicecalls into yourAppControllerbecause you might need to do some bookeeping (for example caching the results inLocalStroage, submitting other Events, etc) and/or notify other screens/components about the loaded data.Think of Events as messages. Here is an example:
You have a View/Presenter pair for displaying a list of records (i.e.
RecordListPresenter). The user clicks on the edit button on one of the records and you have a separate View/Presenter pair for editing the specific record (i.eRecordEditPresenter). Instead of having a reference from yourRecordListPresenterto yourRecordEditPresenterwhich would make them aware of each other and increase the coupling theRecordListPresentersends a message to edit a record (Editevent). TheAppControllerwill act as a Mediator and open load the data and open theRecordEditEditor(it can also only fire an Event with the loaded data and theRecordEditEditorcould reveal itself).But now imagine that you also have a
HeaderPresenterfor displaying some breadcrumb information (like which record it is editing). If you go the "eventless" approach you would need another reference in theRecordListPresenterandRecordEditPresenterto it to drive it. WithEventsthosePresentersdon't have to know that there is aHeaderPresenter. They just fire Events.Now in a complex app you might have many of those independend units.