Javascript Durandal中的多层次路由

Javascript Durandal中的多层次路由,javascript,knockout.js,durandal,Javascript,Knockout.js,Durandal,我正在查看Durandal样本,试图了解路由是如何工作的 shell.js指定了以下路由: { route: ['', 'knockout-samples*details'], moduleId: 'ko/index', title: 'Details...', nav: true, hash: '#knockout-samples' }, { route: 'view-composition',moduleId: 'viewComposition/index', title: ... 在淘

我正在查看Durandal样本,试图了解路由是如何工作的

shell.js指定了以下路由:

{ route: ['', 'knockout-samples*details'], moduleId: 'ko/index', title: 'Details...', nav: true, hash: '#knockout-samples' },
{ route: 'view-composition',moduleId: 'viewComposition/index',  title: ...
淘汰样本下

{ route: '', moduleId: 'helloWorld/index', title: 'Hello World', type: 'intro' },
{ route: 'helloWorld', moduleId: 'helloWorld/index', title: 'Hello World', type: intro', nav: true},
我试图实现的是在
helloWorld
下建立另一个层次结构。大概是这样的:

我试过了,但没有成功:

{ 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'}
然而,这是行不通的


Durandal路由是否不支持此级别的导航?

如果使用Durandal 2.0,则可以设置子路由器。这将允许您在hello world下创建一个新路由器,您可以为视图中的子视图链接其他信息。您可以在文档中查找这些内容,但请确保在视图中设置了路由器,以便在遇到以下路径时

 #helloworld/subview

您已激活helloworld以获得多个导航级别我正在执行以下操作:

唯一可访问的路由器是根路由器,因此要访问子路由器,每次创建子路由器时,我都会将其存储在模块上。 然后,当我想创建另一个级别时,我从模块中获取子路由器并调用createChildRouter

define([], function () {
    return {
        root: null,
        level1: null,
        level2: null
    };
});

define(['plugins/router', 'routers'], function (router, routerContainer) {
    var childRouter = router.createChildRouter()
        .makeRelative({
            moduleId: 'viewmodels/companyplussplat',
            //fromParent: true
            route: 'company'
        }).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 company plus splat");
        },
        deactivate: function () {
            console.log("Deactivating company plus splat");
        },
        router: childRouter
    };
});

define(['plugins/router', 'routers'], function (router, routerContainer) {
    //debugger;
    var childRouter = routerContainer.level1.createChildRouter()
        .makeRelative({
            moduleId: 'orderteailplussplat',
            //fromParent: true
            route: 'company/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
    };
});

我希望这将对您有所帮助。

在创建“孙子”或“曾孙”或更深的子路由器时,技巧是引用相对的父路由器,而不是根路由器。要获取对父路由器的引用,请将包含父路由器的模块作为依赖项添加到“孙子”模块。您可以无限期地嵌套这样的路由器。例如:

myModuleWithChildRouter.js

define(['plugins/router'],  //reference to durandal root router
    function(router) {         

           var _childRouter = router.createChildRouter();

          return { myNewChildRouter: _childRouter}
}
define(['myModuleWithChildRouter'],  //reference to module with child router
    function(childRouterModule) {        

           var _grandChildRouter = childRouterModule.myNewChildRouter.createChildRouter();
          .....

}
MyModuleWithRouter.js

define(['plugins/router'],  //reference to durandal root router
    function(router) {         

           var _childRouter = router.createChildRouter();

          return { myNewChildRouter: _childRouter}
}
define(['myModuleWithChildRouter'],  //reference to module with child router
    function(childRouterModule) {        

           var _grandChildRouter = childRouterModule.myNewChildRouter.createChildRouter();
          .....

}

希望有帮助

我添加了子路由器作为对父路由器本身的引用。也许有点偷偷摸摸,但工作起来很开心:

顶级路由器

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;
});
子路由器

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;
});
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;
});
孙子路由器

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;
});
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;
});

希望能有所帮助。

谢谢。我已经为导航级别做了这些。正如我在问题中提到的,我在定义第二级导航时遇到了问题:)+1这看起来很有希望,可以尝试一下。我刚刚用一张图片更新了我的帖子,上面显示了我需要实现的内容。@Julián我使用了你的代码,它在只有一个节点的情况下工作。但如果我为最低层添加第二条路线,它不会导航到该视图。它和你的代码一起工作吗?你好,我会测试它,明天我会告诉你结果。有人有这个工作的完整例子吗。我对使用此模式的孙辈路线有问题。我不确定这是推荐的方法,但它对我有效