【问题标题】:Multiple levels of routing in DurandalDurandal 中的多级路由
【发布时间】:2013-09-03 00:18:35
【问题描述】:

我正在查看 Durandal 示例,试图了解路由的工作原理。

shell.js 指定了这些路由:

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

knockout-samples下:

{ 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 路由不支持这种级别的导航吗?

【问题讨论】:

    标签: javascript knockout.js durandal


    【解决方案1】:

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

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

    希望有帮助!

    【讨论】:

    • 有没有人有这个工作的完整例子。我在使用这种模式的孙子路线上遇到问题。
    【解决方案2】:

    为了获得多个导航级别,我这样做:

    唯一可访问的路由器是根路由器,因此每次创建子路由器时,我都会将其存储在模块中,以便访问子路由器。 然后,当我想创建另一个关卡时,我从模块中获取子路由器并调用 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
        };
    });
    

    希望对你有所帮助。

    【讨论】:

    • +1 这看起来很有希望,会试一试。我刚刚用一张图片更新了我的帖子,显示了我需要实现的目标。
    • @Julián 我用过你的代码,它适用于只有 1 个节点的情况。但是,如果我为最低级别添加第二条路线,它不会导航到该视图。它适用于您的代码吗?
    • 你好,我测试一下,明天告诉你结果。
    【解决方案3】:

    我添加子作为对父路由器本身的引用。也许有点偷偷摸摸,但工作愉快:

    顶级路由器

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

    希望对您有所帮助。

    【讨论】:

    • 我不确定这是推荐的方法,但它对我有用
    【解决方案4】:

    如果您使用的是 durandal 2.0,您可以设置子路由器。这将允许您在 hello world 下创建一个新路由器,您可以为视图中的子视图链接附加信息。您可以在文档中查找这些内容,但请确保在视图中设置了该路由器,以便当您点击类似

    的路由时
     #helloworld/subview
    

    你已经激活了helloworld

    【讨论】:

    • 谢谢。我已经为导航级别做了这个。正如我在问题中提到的,我在定义第二级导航时遇到了问题:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    • 2013-05-21
    • 2018-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多