Lets look at MVC in the browser:
dojo.connect is an invaluable tool for connecting to various events, both DOM and component generated in a generic, cross-browser, and easy to use API. I love the fact that with Dojo, there is no need for “custom” events, the user components can generate events by simply having methods that are called and they can all be handled with one generic event listener.
The extensive use of MVC in traditional server side web frameworks has caused many developers to associate controllers with request dispatching techniques. However, URI-driven request dispatching based controllers are more of a specific aspect of the server side web framework, where the only channel for receiving inputs from a server is through HTTP requests. A controller that can directly receive inputs from the user through various rich mediums such as keyboard inputs, mouse inputs, etc. and can implement a much more thorough and proactive controller than their counterparts that are confined to looking at requests. Forcing the request dispatcher approach on the browser environment can actually be anachronistic, in contrast to the rich set of events available in the browser.
One of the advantages of using a true event-driven architecture, like that in the browser, is that it affords better encapsulation. Controller code be attached through event listeners within the context of the elements in the view, making it very easy for components and widgets to associate event handler code without crossing component boundaries. The request dispatching approach is the antithesis of encapsulation, forcing logic from every component to go through a central dispatcher.
However, one of the key aspects of the MVC architecture is that the view does not merely arbitrarily create views, but it focuses on rendering the model…
The browser environment provides a great basis for the view and controller, but offers virtually nothing for the model. The model is the true foundation of MVC, and is the primary point through which the view and controller interact. Providing a solid model is integral to true web client/server applications. Establishing a strong model foundation is where Dojo’s architecture truly shines. The model in Dojo is clearly exposed through the Dojo data store API. Dojo distinguishes itself in its mature, well-designed data API that is utilized widely throughout Dojo. The maturity of the API is demonstrated through the large selection of data store implementations that are available, including stores that can adapt to CSV, XML, JSON, HTTP/REST, and many more formats and mediums. The model that is provided through the store API is then consumed by numerous widgets (that provide views and controllers to interact through the store), including the Tree, Grid, filtering select, and others.
The Grid provides an excellent example of how the dojo data API can be leveraged to truly follow the MVC pattern. If you provide a delete button for deleting a row in the grid, the controller does not need to directly affect the view. Rather, you can add an event handler for the button that will call the deleteItem method on the store (defined by the dojo data API) for the selected item, which is effectively controller code interacting with the model (the item from the store). The store will then send a notification event to the grid, which will update the view to eliminate the row corresponding to the deleted item. This follows proper MVC flow, with the controller affecting the model, which then affects the view.
Encapsulation and Integration
Widgets provide a means for encapsulating functionality into a modular component. Widgets typically contain their own MVC pattern internally; Dojo widgets (dijits) exemplify this. The widget architecture includes a template that defines the view. Most of the internal widget code acts as the controller, and widgets can utilize the dojo data API to interact with the model. For example, in the tree widget, a template exists that defines the HTML layout of nodes in the tree. The tree defines drag and drop event handlers that can trigger a model event, which will then result in an update to the nodes being displayed in the tree.
Unfortunately, sometimes widgets can not be completely autonomous. For example, if you had a menu system that controls another “main view” widget (like typical desktop applications do with the top menu pattern) the menu system is not useful by itself. It must act upon the other widget. In order to facilitate this, there may be different levels of controllers in an application. Each widget may have a controller, but a higher level controller may coordinate events received from one widget and route them to calls on other widgets. In Dojo, this is called widget composition. Dojo supports the construction of container widgets that may contain other widgets and coordinate efforts between them.
MVC is here
Recognizing the inherent view and controller structures in the browser and leveraging the strong MVC design in Dojo allows developers to build large scale applications with intelligent code organization following proven MVC patterns of separation of business logic and presentation, whilst organizing applications around conceptual function and purpose.