By Rob Gravelle

Back in the early days of the Angular framework, when it was still called AngularJS, web developers were introduced to the Model-View-ViewModel (MVVM) architectural pattern. Understandably, this required a bit of a paradigm shift for many coders. Moreover, there was much confusion about whether Angular was really Model-View Controller (MVC) or Model-View-ViewModel (MVVM) . In reality, it was neither! Rather, Angular follows a component-oriented architecture. Having said that, Angular does share some of the concepts of both MVC and MVVM. In this tutorial, we'll be looking at a couple of Angular coding examples following MVC and MVVM principles within the context of a component-based architecture.

MVVM: The Short Story

Let's begin by clarifying what MVVM is since it's far less ubiquitous than MVC. MVVM is a refinement of the MVC design whereby the ViewModel in MVVM facilitates the separation of development of the graphical user interface (UI) - i.e. the Presentation Layer. The ViewModel (VM) is responsible for exposing (converting) the data objects from the model in such a way that objects are more easily managed and presented. In this respect, the ViewModel is more model than view, and handles most if not all of the view's display logic. MVVM is a variation of Martin Fowler's Presentation Model design pattern in that a Presentation Model abstracts the View in a way that is not dependent on the specific UI platform. Hence, neither the Presenter or the View are aware of each other.

MVVM was invented by Microsoft architects Ken Cooper and Ted Peters in an effort to simplify event-driven programming of UIs. The pattern was incorporated into Windows Presentation Foundation (WPF) (Microsoft's .NET graphics system) and Silverlight (WPF's Internet application implementation). John Gossman, one of Microsoft's WPF and Silverlight architects, first announced MVVM on his blog in 2005.

Model-view-viewmodel is sometimes also referred to as model-view-binder to reflect the fact that the View handles behaviors, events and data binding information.

MVC vs. MVVM Demos

To illustrate the differences between MVC and MVVM, we'll build a simple example of each.

Let's start by quickly reviewing the main features of the MVC design pattern. It includes:

Model: Model is nothing but data. View: View represents this data. Controller: Controller tells to View to present some of the data from the Model.

In the following snippet, the view is the HTML. Our text is stored in the $scope's sampleText attribute, making it our Model. The Controller is the TextController() function, which updates the view by replacing "{{sampleText}}" with the sampleText variable's value. Thus, the controller manages the relationship between our model and the view.

<!DOCTYPE html> <html ng-app> <head> <title>Angular MVC Demo</title> <script type="text/javascript" src="angular.min.js"></script> </head> <body ng-controller="TextController"> <p>{{sampleText}}</p> </body> <script> function TextController($scope) { $scope.sampleText = 'This is an Angular MVC demo.'; } </script> </html>

Here's the demo of the above code.

Angular employs something called 2-way binding. As it happens, the MVVM design pattern lends itself extremely well to 2-way binding. In Angular, the Controller (the C in MVC) is replaced by the ViewModel (the VM in MVVM). The ViewModel is still a JavaScript function, which is like a controller in that it is responsible for maintaining the relationship between the view and model. However, the difference here is that, if we update anything in view, it gets updated in model. Likewise, change anything in model, it shows up in the view. Not to say that you can't have 2-way binding in MVC. It's just that in the transactional framework associated with client-server interactions where MVC is typically employed, we send the view info to the server to update the model. Meanwhile, in Angular, we're operating on the client side, so we can update associated objects in real time.

Let's see the example that illustrates realtime 2-way binding:

<html ng-app> <head> <title>Angular MVVM 2-way Binding Demo</title> </head> <body> <h2>Angular MVVM 2-way Binding Demo</h2> <br/> <form ng-controller="MultiplicationController"> <label>Number:</label> <input name="number" ng-change="multiply()" ng-model="data.number"> <label>Number entered by User :</label> {{data.number}} <br> <label>Multiplier:</label> <input name="multiplier" ng-change="multiply()" ng-model="data.multiplier"> <label>Number entered by User :</label> {{data.multiplier}} <br> <label>Result:</label> {{data.result}} </form> </body> <script> function MultiplicationController($scope) { $scope.data = {number: 0, multiplier: 0, result: 0}; $scope.multiply = function() { $scope.data.result = $scope.data.number * $scope.data.multiplier; } } </script> </html>

The above code contains two input boxes which takes number and a multiplier to multiply by. The result of the multiplication is shown next to the "Result" label.

Starting with view (the HTML), entering '2' in the number text box and '12' in the multiplier text box updates the view with those values. As soon as any change is made in the view, the ViewModel updates the model with these values. In addition to this, the ViewModel is executing the multiplication, and the result is being assigned to the data.result variable. Since data.result is our model, the change from its initial value causes the view to get updated and the result of the multiplication shown in the HTML:

Here's the Angular MVVM 2-way binding demo.

Conclusion

Remember, while you can imbue elements of both MVC and MVVM structures in Angular, it follows a component-oriented architecture. Components are a logical choice for web apps because of their encapsulation of DOM element, data, and logic.





Rob Gravelle resides in Ottawa, Canada. His design company has built web applications for numerous businesses and government agencies. Email him.

Rob's alter-ego, "Blackjacques", is an accomplished guitar player, who has released several CDs and cover songs. His band, Ivory Knight, was rated as one of Canada's top hard rock and metal groups by Brave Words magazine (issue #92).