使用Durandal:选择使用相同viewModel的所有菜单(isActive)

时间:2013-05-24 16:31:48

标签: durandal sammy.js

我正在使用 Durandal 模板开发asp.net MVC。这个Durandal模板使用Sammy路由解决方案。

我想让我的左侧菜单反映可见路线,如下图所示:

enter image description here

上图是我想要获得的(这不是我到目前为止所做的)。

我的解决方案的特殊性在于每条路线应该是相同的。我的意思是:每条路线都指向'viewmodels / searchTransport',我想用一个参数来过滤我的搜索。

所以我想拥有一个独特的视图/ viewModel,但是使用它们的过滤器来...过滤已经开具发票的元素...

这是我的第一个想法:

    var routes = [
    { url: 'searchTransport',     moduleId: 'viewmodels/searchTransport', name: resource.advancedSearch, visible: true, settings: { transport: true, initValue: 'all' } },
    { url: 'inProgressTransport', moduleId: 'viewmodels/searchTransport', name: resource.inProgress, visible: true, settings: { transport: true, initValue: 'inProgress'  } },
    { url: 'finishedTransport',   moduleId: 'viewmodels/searchTransport', name: resource.finished, visible: true, settings: { transport: true, initValue: 'finished'  } },
    { url: 'invoicedTransport',   moduleId: 'viewmodels/searchTransport', name: resource.invoiced, visible: true, settings: { transport: true, initValue: 'invoiced'  } },
    { url: 'flaggedTransport',    moduleId: 'viewmodels/searchTransport', name: resource.flagged, visible: true, settings: { transport: true, initValue: 'flagged' } },

此菜单显示在我的shell.html中,如下所示:

<ul data-bind="foreach: router.visibleRoutes">
    <li data-bind="css: { menuActive: isActive }">
        <a data-bind="attr: { href: hash }, html: name"></a>
    </li>
</ul>

问题:我的左侧菜单显示所有路线为isActive,因为所有这些路线都使用相同的moduleId。因此我的菜单中的所有元素都被选中(空白背景,见下图)。这不是我需要的;我想只选择应用当前过滤器的元素。

问题:如何组织我的路线,以便能够重复使用相同的路线,但每个路线的参数不同,并且能够在我的左侧菜单中只选择其中一个路线?

我希望我很清楚,否则我会尝试澄清。

感谢。

enter image description here

1 个答案:

答案 0 :(得分:2)

这是我的解决方案:

var routes = [
    // Custom
    { url: 'welcome',       moduleId: 'viewmodels/general/welcome',     name: rscMenu.welcome,      visible: true, settings: {} },
    { url: 'userProfile',   moduleId: 'viewmodels/general/userProfile', name: rscMenu.userProfile,  visible: true, settings: {} },
    // Transport        
    { url: 'generalTransport/:idTran',        moduleId: 'viewmodels/transport/generalTransport',  name: rscMenu.newTransport,    visible: false, settings: { transport: true } },
    { url: 'searchTransport/latestTransport', moduleId: 'viewmodels/transport/searchTransport',   name: rscMenu.latestTransport, visible: true,  settings: { transport: true, initValue: 'latestTransport' } },
    { url: 'searchTransport/inProgress',      moduleId: 'viewmodels/transport/searchTransport',   name: rscMenu.inProgress,      visible: true,  settings: { transport: true, initValue: 'inProgress' } },
    { url: 'searchTransport/finished',        moduleId: 'viewmodels/transport/searchTransport',   name: rscMenu.finished,        visible: true,  settings: { transport: true, initValue: 'finished' } },
    { url: 'searchTransport/invoiced',        moduleId: 'viewmodels/transport/searchTransport',   name: rscMenu.invoiced,        visible: true,  settings: { transport: true, initValue: 'invoiced' } },
    { url: 'searchTransport/flagged',         moduleId: 'viewmodels/transport/searchTransport',   name: rscMenu.flagged,         visible: true,  settings: { transport: true, initValue: 'flagged' } },
    ...

下面是我的shell viewModel:

define(function(require) {

var router = require('durandal/plugins/router'),
    system = require('durandal/system'),
    app = require('durandal/app'),
    logger = require('services/logger'),
    datacontext = require('services/datacontext'),
    config = require('modules/config'),
    rscMenu = require('modules/i18n!nls/menuResource');

var transportRoutes = ko.computed(function () {
        return router.allRoutes().filter(function (r) {
            return r.visible && r.settings.transport;
        });
});
...

以下是我的shell视图:

    <div class="page-sidebar">
        <ul class="accordion" data-role="accordion" data-bind="accordion: {}">
            <li>
                <div>
                    <ul class="sub-menu light" data-bind="foreach: transportRoutes">
                        <li data-bind="css: { menuActive: (url == $parent.router.activeRoute().url) }, attr: { id: settings.initValue }">
                            <a data-bind="attr: { href: (settings.initValue) ? hash.replace(':initValue', settings.initValue) : hash }, html: name"></a>
                        </li>
                    </ul>
                </div>
            </li>
        ...

在侧边栏中选择正确元素的技巧(根据当前视图)位于具有此css: { menuActive: (url == $parent.router.activeRoute().url) }的shell视图中。

希望有一天能帮到某人。