The wikipedia has a good write-up on MVC here. I've clipped a section:
In addition to dividing the application into three kinds of components, the MVC design defines the interactions between them.[5]
- A controller can send commands to its associated view to change the view's presentation of the model (e.g., by scrolling through a document). It can also send commands to the model to update the model's state (e.g., editing a document).
- A model notifies its associated views and controllers when there has been a change in its state. This notification allows the views to produce updated output, and the controllers to change the available set of commands. A passive implementation of MVC omits these notifications, because the application does not require them or the software platform does not support them.[6]
- A view requests from the model the information that it needs to generate an output representation to the user.
In the above definition (and in the original MVC intent), a controller was anything that sent commands to a model in order to change its state. It could also tell the view to change the presentation.
Views generate the output representation of a model to the user. Note that a view can also accept commands from a controller in order to alter the presentation. The implication is that views aren't required to be stateless. They have their own internal models!
***
Where things have gotten messy is the attempt to simplistically map MVC onto web applications. Models live on the server, views live on the client, and controllers are split between the two. That is mostly okay until one runs into complex user interfaces.
The other large bit of messiness arises from the lack of composition in the original MVC description. Controllers and views are associated with one and only one model. There is no guidance on how one structures interactions between MVC components.
In my prior post, I described the composition of several UI components into what is essentially a view. Search and select are simply navigation aids. The interactions are complex enough to warrant decomposition into multiple cooperating objects. Those objects mostly follow the MVC design pattern, but they are doing so in the context of the presentation layer.
***
A few concepts have become more clear to me. One is to think hard about the models necessary to support the presentation layer. Model boundaries often result from the need to obtain information asynchronously from the server and the submodel is nothing more than the server response.
Explicitly handle the cases where the asynchronous response is stale with respect to new model state. In customer navigation example, the user can continue to modify the search criteria while the list of possible matches is being retrieved.
Models process events. Those events can be commands from a controller, raised by other models, be the response to an AJAX request or a timer event.
One should try to have loop-free event chains between models to avoid infinite loops. Ideally one does not want model A subscribed to model B and vice-versa. This isn't always possible but should be aspired to.
MVC components should be standalone. The event processing paradigm can tend to couple together components. In the customer navigation example, one could design the "possible customer list" component to ask the search input component for its current criteria. That makes it harder to isolate those components when testing.
I've found that adding a simpler listener proxy isolates the components. A listener proxy acts on behalf of a component so that the component itself never registers as a listener. The proxy listens to the event and then issues a command to the component (e.g. "queue new search criteria").