The Model-View-Controller (MVC) is one of the most pervasive patterns in software engineering, and is widely accepted as an important paradigm for separation of business logic from presentation logic. Recently there have been some discussions around the use of the MVC pattern within the browser/JavaScript environment. It is easy to look for duplication of the web-framework-specific MVC patterns and miss the significant true (truer in some senses) MVC patterns that already exist in the browser and are augmented by the modern JavaScript toolkit.

The MVC pattern describes the conceptual organization of logic and flow in an application. It would be naive to assume that one needs a module, package, or a class called a “Model”, “View”, or “Controller” in order to implement MVC. There are some great JavaScript libraries that explicitly call out these terms, but the foundation for the view and controller are well established in the browser environment. One can properly leverage and build upon these concepts in the browser to have a well designed MVC structure without necessarily using such terms in your code. MVC can guide design while letting the application’s conceptual function and purpose dictate organization.

Lets look at MVC in the browser:

Controller

The controller is the logic in the application that processes and responds to events. It is easy to identify the foundation for the controller in a browser: the browser environment is completely event driven, and an event system is usually the basis for all controller logic. Controller logic is then implemented through event handlers, which are ubiquitous in client-side JavaScript code. Most rich clients make extensive use of event handlers, which represents the controller portion of the application. While one doesn’t even need a JavaScript toolkit to utilize a controller architecture, using a toolkit such as Dojo certainly helps. Dojo’s 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.

View

In the MVC pattern, the view renders the model into a form suitable for interaction. The heart of the view in the browser should also be obvious: it is the DOM (Document Object Model). Virtually all renderings of information and controls for interaction are done through the DOM. Any web JavaScript developer inevitably is going to be manipulating and interacting with the DOM, and the view pattern is almost impossible to avoid.

Here, JavaScript libraries can provide great benefits. The DOM is notorious for its awkward API, fraught with browser incompatibilities. One of the foremost features any web JavaScript library provides is improved DOM interaction, and this is seen in jQuery, YUI, Dojo, and many others.

The JavaScript toolkits can go beyond just improving on the DOM API. One of the core valuable features of many server side web frameworks is templating; templating allows one to be able to describe and render a view with a friendly, domain specific format. Dojo, which has brilliant templating support, actually has two templating engines. There is a simple lightweight basic templater that is used by many of the base widgets in Dijit; but the true star is the powerful, comprehensive Django templating language (DTL) engine. DTL is a highly regarded templating language with familiar syntax, built on the ideas from many older templating languages, and provides elegant and flexible view design. Dojo’s powerful templating support certainly sets it apart in terms of efficiently implementing the view pattern.

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

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.

At the highest level, the request dispatching notion of page to page navigation can actually be beneficial in rich JavaScript applications, as long as it is understood that it is not the only form of control. The web has a strong concept of sequential page access, and preserving this notion even in “single-page” applications can be very beneficial for user experience, allowing them to use forward and back buttons to navigate and utilize bookmarks to quickly access certain parts of an application. Dojo also has an excellent framework for this page navigation style controller with the dojo.back module. With dojo.back, one registers actions or states to be associated with different URI fragments, and dojo.back can dispatch to the correct application state and view based on user navigation.

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.