I have a ui that looks like this:
+--------+---------------+
| model1 | model details |
| model2 | here, |
| model3 | loaded as the |
| | user selects |
| | a model from |
| | the left. |
| | |
+--------+---------------+
I'm using the MVP pattern to drive this ui.
I'm simplifying a lot here, but in order to divide and conquer I would like to split the Presenter into two: one that handles user gestures in the View on the left (the user changes the Model list in this View, eg sorting) and another Presenter that handles user gestures in the View on the right (the user changes the individual model in this View).
While the Presenter on the left interacts with the entire list of Models, the Presenter on the right interacts with only a single Model: the one the user selects from the list on the left. IOW the ui is driven from left to right.
After the user chooses (ie, clicks) a model on the left, my current implementation looks like (roughly):
LeftPresenter.onModelClick = function(event) {
var model = this.getModelFromEvent(event);
this.view.setSelectedModel(model); // updates list widget on left
RightPresenter.setSelectedModel(model); // notify the other Presenter
}
RightPresenter.setSelectedModel = function(model) {
// lazy load the model from the db, and update the
// view when the model fires the "loadComplete" event
model.bind('loadComplete', this.view.setModel);
model.lazyLoad();
}
Here is the part I am fuzzy on wrt the MVP pattern, or any MVC GUI pattern for that matter:
So my question boils down to: what's the best way to indicate to RightPresenter
that the user selected a model in LeftPresenter
's view?
1. Can a ui be driven by multiple Presenters like this?
Yes
2. Should multiple Presenters be decoupled or can they communicate directly with each other as shown here?
The way I handle it that I have a framework that looks like this
When a event occurs the UI_Object handle the event creating and firing a Command object. Each UI_Object implements a View Interface found in UI_Views and registers itself with UI_View. The Command Objects can access the registered UI Object in UI_View through the interfaces.
For example in one of my metal cutting applications there is a screen element called the HOLD which contains all the parts that hasn't been placed on a sheet of metal for cutting. A part can get into the hold several ways. Loaded from a part file, created by a shape editor, created by our CAD Screen, or picked up from a sheet of metal.
Each of these operations are encapsulated into separate Command objects implementing the Command Design Pattern. When the command object execute it calls.
CuttingScreen.Refresh
CADScreen.Refresh
ShapeEditor.Refresh
Each of these will refresh the respective screen updating the hold.
Now I could add a method to my application interface. MyCuttingApplication.HoldRefresh that will in turn call all three refresh.
But the important point is that your view call a command that uses the interface implemented by the view to update. That the view object registers itself in a lower layer.