1

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

它是一个“配置文件”模块,所以我有一个像这样的顶级路由器:

.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 路由(配置文件*详细信息)声明主模块,并且该模块在定义子内部路由的路由器属性上返回一个子路由器,那么我可以继续使用子模块与每个内部视图组成。

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

意见/我的/details.html

意见/我/resume.html

等等。

使用带有 Breeze 的 unitofwork,此模式将使我能够在每个子视图的停用时强制保存检查,但无需再次重新加载整个配置文件。

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

考虑历史更改导致导航导致与已处于活动状态并正在查看的相同模块的情况。通常,即使模块是相同的类型,它也会被丢弃并创建一个新实例。这有两个例外:

如果模块有与之关联的子路由器。该实例将被保留。如果模块实现了一个特殊的回调,称为 canReuseForRoute,这个函数将被调用,允许开发者决定是否应该丢弃模块。

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

谢谢。

4

1 回答 1

0

我的理解是,如果我使用 splat 路由(配置文件*详细信息)声明主模块,并且该模块在定义子内部路由的路由器属性上返回一个子路由器,那么我可以继续使用子模块与每个内部视图组成。

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

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

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

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

这将为每个视图模型创建一个 url:

#profile/details

#profile/jobsearch

#profile/resume .. etc..

而 myprofile.js 是您的新外壳。(即它的行为方式与 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将作为一个新的外壳,所以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/1to profile/2)表示该模块可以用于路由或不可以重用。

于 2014-03-18T15:14:45.613 回答