Durandal - 子路由器可以重用相同的模型

时间:2014-03-12 03:29:44

标签: url-routing breeze durandal durandal-2.0

我正在尝试配置路由器以允许一个模型用于多个视图。

这是一个'个人资料'模块,所以我有一个像这样的顶级路由器:

.map([{ route: ['profile*details', ''], moduleId: 'myprofile', title: 'Your Profile', hash:'#profile', nav: false } ])

在myprofile.js模块中,我有子路由器:

define(['services/unitofwork', 'services/logger', 'durandal/system', 'durandal/activator', 'viewmodels/profile', 'plugins/router', 'durandal/app', 'services/errorhandler'],
function (unitofwork, logger, system, activator, Profile, router, app, errorhandler) {
    var MyProfile = function () {

        this.router = router.createChildRouter()
        .makeRelative({
            moduleId: 'my',
            fromParent: true
        }).map([
            { route: ['details'], moduleId: 'details', title: 'Details', type: 'intro', nav: true },
            { route: 'search', moduleId: 'jobsearch', title: 'Job Postings', type: 'intro', nav: true },
            { route: 'resume', moduleId: 'resume', title: 'Resume', type: 'intro', nav: true },
            { route: 'account', moduleId: 'account', title: 'Subscription', type: 'intro', nav: true }
        ]).buildNavigationModel();
 }
return MyProfile;
});

我的理解是,如果我使用splat路径(profile * details)声明主模块,并且该模块在路由器属性上返回了childrouter,定义了子内部路由,那么我可以保持使用子模块用每个内部视图组成。

基本上我想将viewmodels / myprofile.js模块与

一起使用

视图/我/ details.html

视图/我/ resume.html

等等。

将单元功能与Breeze一起使用,这种模式可以让我对每个子视图的停用执行保存检查,但不会再次重新加载整个配置文件。

似乎canReuseForRoute属性可能有用,但我认为没有必要给出http://durandaljs.com/documentation/Using-The-Router.html - 模块重用 -

  

考虑历史更改导致导航的情况   结果与已经激活和正在查看的模块相同。   通常,即使模块是相同的类型,它也将是   丢弃并创建一个新实例。有两个例外   这样:

     

如果模块有与之关联的子路由器。实例会   被保存。如果模块有一个特殊的回调实现,则调用   canReuseForRoute,将调用此函数允许开发人员   确定是否应该丢弃该模块。

我错过了什么吗? 是否有可能实现这一目标?

感谢。

1 个答案:

答案 0 :(得分:0)

  

我的理解是,如果我用一个声明主模块   splat route(profile * details),该模块返回了childrouter   在定义子内部路由的路由器属性上,然后   我可以保持使用子模块与每个内部组合   图。

您的理解是正确的。但是,逻辑是你的应用程序中有另一个shell,它可以有自己的菜单。

我不确定你是否实现了它,但无论如何我都会发布我的答案。

在顶级路由器的主shell.js中:

.map([{ route: 'profile*details', moduleId: 'myprofile', title: 'Your Profile', hash:'#profile', nav: false } ])

这将为每个viewmodel创建一个url:

#profile/details

#profile/jobsearch

#profile/resume .. etc..

然而,myprofile.js是你的新shell。 (即它的行为方式与shell.js相同)。

<强> myprofile.js

define(['services/unitofwork', 'services/logger', 'durandal/system', 'durandal/activator', 'viewmodels/profile', 'plugins/router', 'durandal/app', 'services/errorhandler'],
function (unitofwork, logger, system, activator, Profile, router, app, errorhandler) {
    var MyProfile = function () {

        this.router = router.createChildRouter()
        .makeRelative({
            moduleId: 'my',
            fromParent: true
        }).map([
            { route: '', moduleId: 'details', title: 'Details',  nav: true },// This is your home page now at the child router level
            { route: 'search', moduleId: 'jobsearch', title: 'Job Postings', nav: true },
            { route: 'resume', moduleId: 'resume', title: 'Resume', nav: true },
            { route: 'account', moduleId: 'account', title: 'Subscription', nav: true }
        ]).buildNavigationModel();
 }
return MyProfile;
});

请注意,第一条路线为空,因为这是您的新主页。 我省略了type:'intro'因为你的情况不需要。(这只是一种分类路线的方法 在UI)

myprofile将充当新shell,因此myprofile.html可能如下所示:

   <div class="col-md-2">
   <ul class="nav" data-bind="foreach: router.navigationModel">
                <li data-bind="css: { active: isActive }">
                    <a data-bind="attr: { href: hash }, html: title"></a>
                </li>
            </ul>
    </div>
   <div class="col-md-10">
          <!--ko router: { transition:'entrance', cacheViews:true }--><!--/ko-->
      </div>

你可以撰写一个新的nav.html或者像我一样做。 您还可以将子菜单设置为水平。我个人更喜欢垂直("col-md-2")。

这肯定会使你能够保持使用子模块来构建每个内部视图,Unitofwork只会在子级别加载。

当您想要导航时,

canReuseForRoute可用于某些情况,例如parameterized routes 在相同的Viewmodel和更改的参数内(例如profile/1profile/2)表示此模块可以重用于路由。