Modern applications today tend to be very complex and offer a plethora of features. As such, developers must constantly strive to find a good balance per the separation of concerns to create solid applications and enable good unit testing. Because of these needs MVC has returned to the forefront in recent years as a way to achieve this separation. However, with Ajax there is more logic within the view interns of how the view should work for the user. With traditional MVC this leads to a lot of code being placed in the View to facilitate these interactions. This leads to a lot of extra code being put in the view and developers asking the question “should there be another layer somewhere?”.
As part of the .NET 3.0 release Microsoft began work on the Microsoft Windows Presentation Foundation (WPF). This new framework used a declarative markup language (XAML) to build user interfaces, this meant that the code previously hidden in Windows Form for creating controls and placing them was removed. Perhaps once of the most profound things to come out of this framework was the notion of declarative binding. Whether this was actually invented here is unknown to me, it is simply the first example I saw of it.
Using these declarative bindings we (developers) were able to remove much of the get/set code that had created so much clutter over the years. This formed the basis for the Model View ViewModel pattern (MVVM) where we actually split the V into the View and the ViewModel. The ViewModel taking on much of the code that had originally cluttered our views, thus becoming the new layer we so desperately sought.
MVVM on the Web
This is a very basic example, but what it does is “bind” the FirstName and LastName members of the “viewModel” object. This example is showing off one way binding, since the user cannot expect to update the text content of a . So if we want to use two way binding, we would need to use the binding with form elements:
By itself the value: binding will not give you the two way binding you would want on a form textfield, in fact it has very little to do with the two way binding you want. The key for two way binding is the user of Knockout Observables. If you notice the definition of our object contains two refers to ko.observable. Using this makes the member special. It tells Knockout to watch this binding for changes and update the view model when changes occur.
In the AppViewModel object, we are also defining a “computed” observable. This will watch a field (or fields) for changes and update accordingly. There are common used for composed properties which use the data from a variety of other properties (or members). In the case of this example, any change to the value of firstName or lastName will update the value in fullName and cause the to update its value to display the changed value. Side note: buy default, for value: the binding update occurs onBlur as opposed to onKeyDown, this is configurable.
With our current example, when you blur out of a textfield the span will update, but what would we have to do for the update to be real time, as they are typing. Simple, we specify the valueUpdate setting on the binding:
As you can see, we specify that the update to the view model should occur after key down. This will automatically handle everything for us and since we are updating the view model which is using a computed observable this change is then immediately reflected in the tag. So without writing any JS code, we have achieved this effect.
The MVVM approach to View development is something that I highly recommend. The biggest thing people seem to have trouble with is they want to view it as a replacement for something like MVC. It isn’t. Its a augmentation. The M in MVVM (Model) only refers to the output of a Controller, not a Model from MVC, although it could. The principle point of emphasis in MVVM in that the ViewModel handles the interactions. ViewModels handle client validation and view interaction, they don’t do any kind of persistence, although they can be backed by a Model which does provide some level of persistence.