IT:AD:Durandal.JS:HowTo:Create a ViewModel
Summary
Durandal renders modules with views. Create a view by adding an html file to your application. Views should have one root element. The view locator matches views to your modules. Use IT:AD:Knockout.JS bindings to synchronize a view with its module.
Recipe
- We already saw what a module is: IT:AD:Durandal.JS:HowTo:Create A Module
- A ViewModel is just a Module that is placed in the
app/ViewModelsdirectory. - Each
ViewModelis kept in theapp/viewmodelsdirectory and will match a *.js file of the same name, in theapp/viewsdirectory:
+---App ¦ +---durandal ¦ ¦ ... ¦ +---viewmodels ¦ ¦ +---MyView.js ¦ +---views ¦ ¦ +---MyView.html
- As it's just a Module, like every other Module in Durandal, it
- starts with a IT:AD:Require.JS
requirestatement, listing its dependencies, and how to refer to them them within the scope of the object it returns. - returns an object (a singleton) or a class definition (unique per require context).
define(
['durandal/app', 'durandal/system'],
function (app, system) {
var model = function () {
//add properties of any kind/name you like:
this.title = 'Talking Heads';
this.subtitle = 'Blah, blah...';
};
//add methods:
model.goBoing = function (view) {...}
model.prototype.viewAttached = function (view) {
//you can get the view after it's bound and connected to it's parent dom node if you want
this.goBoing();
};
//return singleton:
return model;
});
The properties defined (title, and subtitle) and the methods (goBoing, viewAttached…although viewAttached is a bit different) belong to the model backing the View.
LifeCycle Methods
Note that the viewAttached is not a custom method , but a LifeCycle events, invoked by the Composition module
-
- Of common:
- viewAttached(view)
- activate()
- deactivate()
Therefore, the following will show
define(
['durandal/app', 'durandal/system'],
function (app, system) {
var model = function () {
//add properties of any kind/name you like:
this.title = 'Talking Heads';
this.subtitle = 'Blah, blah...';
};
//add methods:
model.goBoing = function (view) {alert('boing...');}
model.prototype.viewAttached = function (view) {
//you can get the view after it's bound and connected to it's parent dom node if you want
this.goBoing();
};
model.prototype.activate = function(args){
alert('bing...');
//If invoked with arguments, will be called with the following args:
//as per http://durandaljs.com/documentation/Router/
//{
//splat:['1'],
//routeInfo:{ ...the original route info object... },
//router:{ ...the router itself... }
//}
}
//return singleton:
return model;
});
The above sill go Boing the first time it is loaded – as well as Bing…and then Bing every time you come back to the page.
This explains why the Shell…which is nothing more than a View itself looks like this:
define(['durandal/plugins/router'],
function (riyter) {
return {
router: router,
activate: function () {
//When Shell Activates -- whic is probably the only shell that only activates once --
//tell the imported singleton router to show the following page:
return router.activate('movies/show');
}
};
});