How can I use a class for my shell viewmodel in Durandal? How can I use a class for my shell viewmodel in Durandal? typescript typescript

How can I use a class for my shell viewmodel in Durandal?


The problem is your router is not resolving your shell.ts module.

All your other viewmodels are passing through the router.getActivatableInstance method and are being instantiated and having __moduleId__ affixed to them. Except your shell.ts module.

This is a quick and dirty way to get your shell.ts module to work.

Inside your main.ts you can require your shell.ts module:

import _shell = module('shell');

Then, still inside your main.ts you can instantiate your shell class and assign it the moduleId.

var shell = new _shell.Shell();shell.__moduleId__ = _shell.__moduleId__;_app.setRoot(shell, 'entrance');

Not the prettiest thing you've ever seen. But it gets the job done. Thats pretty much doing the same thing as the getActivatableInstance override your doing.. Since, your shell is not passing through the router.js module, you have to do it manually.


Another option is to export the class as the module for Duranal.note: this method also works for viewmodels.

A working example based on nuget's "Durandal Starter Kit":

    import router = require('plugins/router')    import app = require('durandal/app')    class Shell {        router =  router;        public search() {            //It's really easy to show a message box.            //You can add custom options too. Also, it returns a promise for the user's response.            app.showMessage('Search not yet implemented...');        }        public activate() {            router.map([                { route: '', title: 'Welcome', moduleId: 'viewmodels/welcome', nav: true },                { route: 'flickr', moduleId: 'viewmodels/flickr', nav: true },            ]).buildNavigationModel();            return router.activate();        }    }    // Magic happens here:    export = Shell;

The original 'js' code:

    define(['plugins/router', 'durandal/app'], function (router, app) {        return {            router: router,            search: function() {                //It's really easy to show a message box.                //You can add custom options too. Also, it returns a promise for the user's response.                app.showMessage('Search not yet implemented...');            },            activate: function () {                router.map([                    { route: '', title:'Welcome', moduleId: 'viewmodels/welcome', nav: true },                    { route: 'flickr', moduleId: 'viewmodels/flickr', nav: true },                ]).buildNavigationModel();                return router.activate();            }        };    });