I am looking at the Durandal samples trying to understand how routing works.
The shell.js specifies these routes:
{ route: ['', 'knockout-samples*details'], moduleId: 'ko/index', title: 'Details...', nav: true, hash: '#knockout-samples' },
{ route: 'view-position',moduleId: 'viewComposition/index', title: ...
under knockout-samples
:
{ route: '', moduleId: 'helloWorld/index', title: 'Hello World', type: 'intro' },
{ route: 'helloWorld', moduleId: 'helloWorld/index', title: 'Hello World', type: intro', nav: true},
What I am trying to achieve is having another hierarchy under helloWorld
. Something like this:
I tried this but no luck:
{ route: '', moduleId: 'helloWorld/index', title: 'Hello World', type: 'intro' },
{ route: 'helloWorld*details', moduleId: 'helloWorld/index', title: 'Hello World', type: 'intro', nav: true, hash:'#knockout-samples/helloWorld'}
However, this is not working.
Does Durandal routing not support this level of navigation?
I am looking at the Durandal samples trying to understand how routing works.
The shell.js specifies these routes:
{ route: ['', 'knockout-samples*details'], moduleId: 'ko/index', title: 'Details...', nav: true, hash: '#knockout-samples' },
{ route: 'view-position',moduleId: 'viewComposition/index', title: ...
under knockout-samples
:
{ route: '', moduleId: 'helloWorld/index', title: 'Hello World', type: 'intro' },
{ route: 'helloWorld', moduleId: 'helloWorld/index', title: 'Hello World', type: intro', nav: true},
What I am trying to achieve is having another hierarchy under helloWorld
. Something like this:
I tried this but no luck:
{ route: '', moduleId: 'helloWorld/index', title: 'Hello World', type: 'intro' },
{ route: 'helloWorld*details', moduleId: 'helloWorld/index', title: 'Hello World', type: 'intro', nav: true, hash:'#knockout-samples/helloWorld'}
However, this is not working.
Does Durandal routing not support this level of navigation?
Share Improve this question edited Aug 30, 2013 at 11:52 GETah asked Aug 30, 2013 at 9:53 GETahGETah 21.4k7 gold badges66 silver badges108 bronze badges4 Answers
Reset to default 8When creating a 'grandchild' or 'great grandchild' or deeper child router, the trick is to reference the relative parent router, not the root router. To get a reference to the parent router, add the module that contains the parent router as a dependency to your 'grandchild' module. You can nest routers like this indefinitely. For example:
myModuleWithChildRouter.js
define(['plugins/router'], //reference to durandal root router
function(router) {
var _childRouter = router.createChildRouter();
return { myNewChildRouter: _childRouter}
}
myModuleWithGrandchildRouter.js
define(['myModuleWithChildRouter'], //reference to module with child router
function(childRouterModule) {
var _grandChildRouter = childRouterModule.myNewChildRouter.createChildRouter();
.....
}
Hope that helps!
To get more than one navigation level I'm doing this:
The only accesible router is the root router so to have acces to the child routers, everytime that I'm creating a child router, i store it on a module. Then, when i want to create another level, I get the child router from the module and call createChildRouter.
define([], function () {
return {
root: null,
level1: null,
level2: null
};
});
define(['plugins/router', 'routers'], function (router, routerContainer) {
var childRouter = router.createChildRouter()
.makeRelative({
moduleId: 'viewmodels/panyplussplat',
//fromParent: true
route: 'pany'
}).map([
{ route: 'order/:orderID', moduleId: 'orderdetail', title: 'Order', nav: false },
{ route: 'order/:orderID*details', moduleId: 'orderdetailplussplat', title: 'Order plus splat', nav: false }
]).buildNavigationModel();
routerContainer.level1 = childRouter;
return {
activate: function () {
console.log("Activating pany plus splat");
},
deactivate: function () {
console.log("Deactivating pany plus splat");
},
router: childRouter
};
});
define(['plugins/router', 'routers'], function (router, routerContainer) {
//debugger;
var childRouter = routerContainer.level1.createChildRouter()
.makeRelative({
moduleId: 'orderteailplussplat',
//fromParent: true
route: 'pany/order/:orderID'
}).map([
{ route: 'orderline/:orderlineID', moduleId: 'orderlinedetail', title: 'Order line detail', nav: false },
]).buildNavigationModel();
routerContainer.level2 = childRouter;
return {
activate: function (orderID) {
console.log('Activating order detail for: '+ orderID +' plus splat');
},
deactivate: function () {
console.log('Deactivating order detail plus splat');
},
router: childRouter
};
});
I hope this will help you.
I added the child as a reference to the parent router itself. Maybe a bit sneaky, but working happily:
Top level router
define(["plugins/router"], function (router) {
// create the constructor
var ctor = function() {
};
ko.utils.extend(ctor.prototype, {
activate: function () {
//var self = this;
var map = router.makeRelative({ moduleId: "viewmodels" }).map([
{ route: "", moduleId: "index", title: "Overview", nav: true, hash: "#/", enabled: true },
{ route: "data*details", moduleId: "data/shell", title: "Data Loading", nav: true, hash: "#/data", enabled: false },
{ route: "reporting*details", moduleId: "reporting/shell", title: "Reporting", nav: true, hash: "#/reporting", enabled: true },
{ route: "query*details", moduleId: "query/shell", title: "Query", nav: true, hash: "#/query", enabled: true },
{ route: "login", moduleId: "login", title: "Login", hash: "#/login", state: "out" }
]);
return map.buildNavigationModel()
.mapUnknownRoutes("404")
.activate();
});
});
return ctor;
});
Child router
define(["plugins/router"], function (router) {
var childRouter = router.createChildRouter()
.makeRelative({
moduleId: "viewmodels/reporting",
fromParent: true
}).map([
{ route: "", moduleId: "index", title: "Reporting", nav: false, hash: "#/reporting" },
{ route: "standard", moduleId: "standard", title: "Standard Reports", nav: true, hash: "#/reporting/standard" },
{ route: "alert*details", moduleId: "alert/shell", title: "Alerts", nav: true, hash: "#/reporting/alert" }
]).buildNavigationModel();
// for alerts
router.child = childRouter;
var vm = {
router: childRouter
};
return vm;
});
Grandchild router
define(["plugins/router"], function (router) {
var grandchildRouter = router.child.createChildRouter()
.makeRelative({
moduleId: "viewmodels/reporting/alert",
fromParent: true
}).map([
{ route: "", moduleId: "index", title: "Alerts", hash: "#/reporting/alert" },
{ route: ":id", moduleId: "case", title: "Alert Details", hash: "#/reporting/alert" }
]).buildNavigationModel();
var vm = {
router: grandchildRouter
};
return vm;
});
Hope that helps.
If you are using durandal 2.0 you can set up the child router. This will allow you to create a new router under the hello world that you can chain on additional info for for sub views in your view. You can look these up on the docs but make sure you set up that router within the view so when you hit a route like
#helloworld/subview
you have already activated helloworld