我正在尝试配置路由器以允许一个模型用于多个视图。
这是一个'个人资料'模块,所以我有一个像这样的顶级路由器:
.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,将调用此函数允许开发人员 确定是否应该丢弃该模块。
我错过了什么吗? 是否有可能实现这一目标?
感谢。
答案 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/1
到profile/2
)表示此模块可以重用于路由。