Question

I'm a Beginner trying to learn SPA / Durandal, Knockout etc...

Need some help with my routes for a Admin drop down button.

Here are my routes in the shell.js so far:

var routes = [
            { route: '', moduleId: 'home', title: 'Home', nav: 1 },
            { route: 'downtime', moduleId: 'downtime', title: 'Downtime', nav: 2 },
            { route: 'downtimeadd', moduleId: 'downtimeadd', title: 'Add A New Downtime', nav: false, settings: { admin: true } },
            { route: 'production', moduleId: 'production', title: 'Production', nav: 4 }];

I've also created adminRoutes in the shell.js to bind to the view with KO:

var adminRoutes = ko.computed(function () {
        return router.routes.filter(function (r) {
            return r.settings.admin;
        });
    });

From research, they say that router.routes is an array, but when I bind this to my view the button shows 0 items for the drop down.

When I do (below) I can get all the routes, but I only need the admin routes...

var adminRoutes = ko.computed(function () {
        return router.routes;
    });

How should I proceed? It seems like router.routes is not actually an array? If I try to print it out to the console:

console.log(router.routes[0]); //Chrome says its undefined...
console.log(router.routes); //Shows array of size 4...

Yup no clue... Help would be appreciated!

Update:-------------------------------------------------------------------

Even after RainerAtSpirit's suggestions I still get an empty array when I filter in code.

var router = require('plugins/router');
//Array size 4
console.log(router.routes); 

//Array size 0
console.log(router.routes.filter(function (r) { return r; })); 

However when I run this in the "chrome console":

var router = require('plugins/router')
router.routes.filter(function (r) { return r; })

I do get the array back, so I don't know why in code it doesn't work.

Was it helpful?

Solution

I got this to work, although maybe not as perfectly as I would like.

The first problem I noticed was an issue that others were not seeing. In my example (with druandal 2.0 from the HotTowel template version 1.1 for VS 2013) I noticed that this code for adding the adminRoutes was called prior to the activate method. Therefore, my route.routes was an empty array. To fix this problem, I switched to just using the array of routes that the routes are getting mapped from the config.js with (note: config.routes rather than route.routes):

var adminRoutes = ko.computed(function () {
    return config.routes.filter(function(r) {
        return r.admin;
    });
});

Finally, I'm return "r.admin". This is the part that would like to make work better because I added an admin property to the admin route without the "settings" group, see "admin: true":

var routes = [
    { route: '', moduleId: 'equipment', title: 'Equipment', nav: 1 },
    { route: 'testresults', moduleId: 'testresults', title: 'Test Results', nav: 2 },
    { route: 'testresultdetail/:id', moduleId: 'testresultdetail', title: 'View a test result', nav: false },
    { route: 'testresultadd', moduleId: 'testresultadd', title: 'Add a Test Result', nav: false, caption: '<i class="fa fa-plus"></i> Add Test Result', admin: true }
];

With these two changes, the menu item showed up.

OTHER TIPS

In knockout when you make a property to be observable it turns in to a function wrapping ,so when you need to get the actual value you need to access it as a function. That means

router.routes[0] will be undefined but router.routes()[0] will work correct !

You can try

var adminRoutes = ko.computed(function () {
        return router.routes().filter(function (r) {
            return r.settings.admin;
        });
    });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top