Many moons ago I used to write code with Ruby on Rails (please don’t throw shoes at me).

This was my first experience with a dynamically typed language and the MVC design pattern. Rails was pretty strict about the separation of concerns, but the code still ended up being peppered with small inline hacks in the View layer to make things work because there wasn’t a dedicated layer for shaping the domain model to the application model. The purity of the pattern wasn’t preserved.

MVC pattern

Fast forward a few blue moons and I started working on WPF/Silverlight apps using the MVVM design pattern. MVVM is a derivative of both MVC and Fowler’s presentation model. Aside from other problems, the one that bugged me the worst was MVVM’s lack of description of where action code belongs. Input from the view layer was implicitly handled either by a controller (MVVM-C, breaking the classic pattern) or a thick viewmodel (making the viewmodels enormous).

MVVM pattern

During my MVVM time, I once worked on a refactoring team that held a daily religious debate whether or not to use controllers or thick VMs, which was not helped by the fact that the legacy code had a nested viewmodel hierarchy. Controllers were supposed to have a supervisory function over multiple viewmodels, but since the viewmodels were nested in a parent viewmodel you didn’t really need the controller, but now the parent viewmodel is too thick, but the controller…and so it went.

There are a few other noticeable problems with MVVM, such as dealing with binding collections, however the one thing that MVVM did extremely well was the explicit viewmodel layer that converted the domain model (coming from the data source) into the application model (which transformed data that views can consume). The viewmodel also allowed the existence of a viewmodel state, such that the user could interact with the views, but still have the option to cancel the input before it reached the model. This may seem only marginally useful, since you could control local transactions at the model layer, but in reality you sometimes have additional processing involved (such as execution of business or validation rules) which makes the existence of additional states between the view and the model layer necessary.

Ideally, we would be looking for an MVC implementation that would allow us to cleanly separate the domain model obtain for a data source from the application model exposed to the view layer.

MVC with domain/application model conversion

Being familiar with the MVVM approach using C#/XAML and the lack of elegant code it sometimes produced, I approached WinJS with some degree of trepidation. The API and the language could have fundamental limitations that wouldn’t allow a clean client architecture. But I was wrong.

 

WinJS introduces a beautiful concept of declarative bindings that expose powerful functionality for the developer to shape the domain data. This is done through the data-win-bind and data-win-bindsource custom attributes (fully HTML5 compliant). data-win-bindsource is now deprecated as of the RTM release, however I hope that Microsoft leaves that feature in the future, since it allows the developer to declaratively set different contexts for different DOM elements in the HTML code.

Part of the reason why you need an entire viewmodel class in C#/XAML as the datacontext for the view layer is because you can only have one datacontext for the view (there are ways to hack around this, by nesting viewmodels in a parent viewmodel or using the locator pattern). With data-win-bindsource you can set the individual context for individual DOM elements, further decoupling the organization of the view from the organization of the data that it is bound to.

WinJS also gives you several options on how to set the bindings between application model objects and the view layer. If using the WinJS.Binding class in Javascript you need to have knowledge of the view layer from other parts of the code, hence making the use of MVVM impossible. The bindings are also one-way, if you need to react to user input, some code somewhere needs to refresh the bindings that draw data to the view layer from the application model.

The new features of WinJS and limitations of MVVM tend to steer the WinJS developer towards the MVC design pattern. It has been in use in the Javascript/HTML world for 15+ years and can be implemented without needing any additional frameworks beyond the base WinJS API.

Let’s dive into the matter of things and write some MVC code.

We will start with default.js. Every WinJS application contains a module that handles the initialization of the application and calls any initializations routines written by the developer. In our case, we only want to initialize our Controller. This is the code from the onactivated handler in our sample application:

app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
// TODO: This application has been newly launched. Initialize
// your application here.
} else {
// TODO: This application has been reactivated from suspension.
// Restore application state here.
}
args.setPromise(WinJS.UI.processAll());

Controller.Initialize();
}
};

Next, we will want to create our Model layer code. In our Model layer, we will create a simple object with one text property that will propagate its contents to the View layer. The Model object is made observable by the WinJS.Binding.as method, similar to using INPC:

// Declare model data structure
var _model = {
modelProperty: “I am a shiny property.”
};

// Expose the model data structure as observable to the view
var Model = WinJS.Binding.as(_model);

This separation of observable and inobservable models creates a weak domain/application model separation, a strong implementation of the separation is discussed further down.

The View layer is two lines of HTML code, declaring a paragraph that display an initial string value and gets modified when the second element, a button, is clicked:

<body>
<p id=”textOut” data-win-bind=”innerHTML: modelProperty” style=”font-size:80px;”></p>
<input id=”button”  type=”button” value=”No, you are not.” style=”font-size:50px; color:yellow;” />
</body>

Finally, our Controller creates the binding between the observable Model object and the View layer, as well as hooking up a handler to the “click” event of the button:

// Declare handler function for the button
function handleButtonClicked(event) {
Model.setProperty(“modelProperty”, “I am no longer shiny. :(“);
};

// Declare controller object
var Controller = {
Initialize: function () {
WinJS.Binding.processAll(document.getElementById(“textOut”), Model);
document.getElementById(“button”).addEventListener(“click”, handleButtonClicked, true);
}
};

As you can see, the Controller is aware of both the Model and the View layer and sets the value to the bound object using the setProperty method of the WinJS.Binding API.

There are several variations to this approach:

First, I would advocate using the Module pattern and exposing observable module interfaces using WinJS.Namespace and WinJS.Class APIs. This introduces modularity and information hiding to the MVC pattern. This approach also creates an explicit separation of the domain model (hidden inside the module) and the application model (exposed via WinJS.Namespace and WinJS.Class).

Second, it is not always necessary to use the Controller and Binding API to manually bind the View layer to the application model. Depending on the version of code you are using, WinJS may expose a declarative way to perform the binding in the view layer. An example of this would be the data-win-bindsource attribute.

Whichever way you proceed to design your WinJS application, I hope that you consider the lessons of MVVM and create clean, maintainable code that is clearly organized.