好吧,我对durandal很新。我真的在努力实现这一目标。
以下是我要做的事情:主要导航受到收件箱,草稿,提交等的影响。点击这些,为用户提供一个出现在主导航侧面的子菜单。这个子菜单是由我从服务器获取的json数据生成的。单击子菜单中的选项应基于文档的ID在查看器视图模型中打开文档。
实施例
用户点击收件箱 2.菜单出来,包含收件箱中的文件。用户点击视图 3.单击的文档将显示给用户。 所以当他们达到这一点时,我希望网址是mysite.com/#inbox/viewer/123456(123456是文件记录)
我只是找不到与此相似的正常例子,并且想知道是否有人可以帮我指出正确的方向。
我通过将每个主导航链接创建到模块,并在每个模块中都有一个文档窗口来实现它,但我认为必须有更好的方法。所以我要做的是将我的子导航保持在shell中。我不希望每个主要导航项都有一个模块。
这是我现在的shell代码: shell.js
define(['durandal/system', 'services/logger', 'plugins/router', 'durandal/activator'], function (system, logger, router, activator) {
//#region Internal Methods
function log(msg, data, showToast) {
logger.log(msg, data, system.getModuleId(shell), showToast);
}
function logError(msg, data, showToast) {
logger.logError(msg, data, system.getModuleId(shell), showToast);
}
function navigateRoute(hashValue) {
var target = hashValue.hash;
$("body").addClass("subnav-active");
document.cookie = "subNav=true";
$(target).addClass("current");
router.navigate(target, {replace: true, trigger: false });
}
var routes = [
{ route: '', hash: '#home', moduleId: 'home', title: '', nav: false, cssClass: 'icon-inbox' },
{ route: 'inbox', hash: '#inbox', moduleId: 'inbox', title: 'Inbox', nav: true, cssClass: 'icon-inbox' },
{ route: 'drafts', hash: '#drafts', moduleId: 'drafts', title: 'Drafts', nav: true, cssClass: 'icon-file-alt' },
{ route: 'submitted', hash: '#submitted', moduleId: 'submitted', title: 'Submitted', nav: true, cssClass: 'icon-hand-right' },
{ route: 'completed', hash: '#completed', moduleId: 'completed', title: 'Completed', nav: true, cssClass: 'icon-check' },
{ route: 'settings', hash: '#settings', moduleId: 'settings', title: 'Settings', nav: true, cssClass: 'icon-cog' }
];
//#endregion
var shell = {
activate: function () {
router.on('router:route:not-found', function (fragment) {
logError('No Route Found', fragment, true);
});
return router.makeRelative({ moduleId: 'viewmodels' }) // router will look here for viewmodels by convention
.map(routes) // Map the routes
.buildNavigationModel() // Finds all nav routes and readies them
.activate(); // Activate the router
}
,
router: router,
navigateRoute: navigateRoute
};
return shell;
});
shell.html
<div class="main-wrapper wrapper">
<div class="container_template">
<header class="pageheader">
<nav class="mobile-nav">
<a class="menu-button" href="#main-navigation">
<i class="icon-reorder"></i><span>Menu</span>
</a>
</nav>
<h1 class="logo">template</h1>
<nav class="nav-user">
<a class="close" href="#">
<i class="icon-chevron-right"></i>
<span>Main</span>
</a>
</nav>
</header>
<!-- Begin Header/Navigation -->
<div class="main-navigation" role="banner">
<div class="main-navigation-inner inner">
<nav class="navigation">
<ul data-bind="foreach: router.navigationModel">
<li>
<a class="nav-button" data-bind="attr: {'data-target': hash,}, css: {'nav-button' : isActive, active: isActive }, click: function(hash) { $root.navigateRoute(hash);return true},">
<i data-bind="css: cssClass"></i>
<span data-bind="html: title"></span>
</a>
</li>
</ul>
</nav>
</div>
</div>
<!-- End Header/Navigation -->
<!-- Sub Navigation Elements -->
<!--This is my sbumenu-->
<div id="inbox" class="navigation-sub">
<div class="navigation-sub-inner inner">
<div class="navigation-sub-header">
<a class="close" href="#">×</a>
<h3>Inbox</h3>
</div>
<div class="navigation-sub-search">
<form>
<input type="text" placeholder="Search" />
<button>Go</button>
</form>
</div>
<ul data-bind="contentsOfInbox">
<li>
<a data-bind="href : linktoDocuemntViewer" href="" class="form-open">
<i class="icon-file-alt"></i><span data-bind="html: NameofDocumentHere"></span>
<span class="date" data-bind="html: DateOfDocumentHere"></span>
</a>
</li>
</ul>
</div>
</div>
<!-- End SUB NAV -->
<!--Begin Main-->
<!--Documents would appear here-->
<div class="main" data-bind=" router: { cacheViews: false }">
</div>
<!-- End Main -->
</div>
感谢您的帮助
答案 0 :(得分:0)
对于你想要做的事情,听起来好像使用navigationModel是行不通的。根据我的经验,navigationModel和route是1对1的关系。你要做的是让一条路线的参数与多个菜单项相关联。为此,您应该分开菜单和路线。请记住,您只需将javascript对象和集合绑定到html元素即可。 router.navigationModel属性就是这个,它是根据您定义的路由构建的javascript对象的集合。当你调用它正在做的.buildNavigationModel()时,建立一个新的javascript对象集合,你可以绑定到你的菜单html。没有什么能阻止您在shell viewmodel上创建一个全新的属性,该属性包含您自己的javascript菜单对象的自定义集合并将其绑定到您的UL / LI导航html。如果你将这个新的菜单集合作为computedObservable,那么你可以根据需要以懒惰的方式添加它,并且因为它与knockout绑定,所以更改会自动出现在UI中。我已经在许多不同的项目上完成了这项工作并且工作正常。我在后端构建一个菜单表,然后只返回用户有权访问的项目,并使用它来构建我的UI菜单。为了使导航工作,我将urlhash保留在表中并将其绑定到锚标记。当您创建路由时,您不必设置哈希属性,路由器插件将为您处理。因此,对于您请求的示例,请创建如下菜单集:
{ displayname: 'Inbox' cssClass: 'icon-inbox', urlHash: '' children[
{ displayname: 'Doc 1' cssClass: 'icon-message', urlHash: 'inbox/viewer/12345' },
{ displayname: 'Doc 2' cssClass: 'icon-message', urlHash: 'inbox/viewer/12346' },
{ displayname: 'File 1' cssClass: 'icon-message', urlHash: 'inbox/viewer/12347' }]}
创建一条这样的路线:
{ route: 'inbox/viewer/:messageId', moduleId: 'home', title: '', nav: false, cssClass: 'icon-inbox' },
有关将参数传递给路径的信息,请参阅durandal docs
将此菜单显示为来自shell的computedObesrvable,并将其绑定到您的UL / LI菜单html而不是router.NavigationModel。需要时,使用服务器中的新数据更改收件箱菜单的children属性的内容。