【问题标题】:How to use Durandal's createChildRouter如何使用 Durandal 的 createChildRouter
【发布时间】:2013-11-14 07:27:03
【问题描述】:

我整天都在苦苦挣扎,无法弄清楚如何在我的基于热毛巾 (MVC4 SPA) 的项目中使用 Durandal 正确创建子路由器。这是我目前拥有的:

shell.js

var routes = [
    { route: '', moduleId: 'home', title: 'Home', nav: 1 },
    { route: 'inventory/index', moduleId: 'inventory/inventory', title: 'Inventory', nav: 2 }];
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

inventory.js

define(['services/logger', 'plugins/router'], function (logger, router) {
    var title = 'Details';
    var childRouter = router.createChildRouter()
      .makeRelative({
         moduleId: 'viewmodels/inventory',
         fromParent: true
      }).map([
            { route: '', moduleId: 'inventory', title: 'Inventory', nav: 3 },
            { route: 'items', moduleId: 'items', title: 'Items', nav: 4 }])
        .buildNavigationModel();
    var vm = {
       router: childRouter,
       activate: activate,
       title: title
    };

    return vm;

    //#region Internal Methods
    function activate() {
       logger.log(title + ' View Activated', null, title, true);
    }
    //#endregion
});

我目前遇到的问题:

  1. 当我点击库存视图时,它会被激活两次
  2. 没有其他导航选项可见,尽管右上角出现了一些空的 3D 圆角矩形...我不确定这是无法消失的进度条还是某些失败的导航元素。

我的项目文件是这样组织的:

【问题讨论】:

  • 检查在 shell.js 中将显式路由 inventory/index 更改为 splat 路由 inventory/index/*whatever 是否有所不同。见durandaljs.com/documentation/Using-The-Router
  • @RainerAtSpirit 它消除了对详细信息视图的额外激活,但控制台日志随后报告“LOG: Route '*whatever' Not Found”(我将错误报告代码更改为system.log('Route \'' + coreFragment + '\' Not Found'); 所以我有一些线索是怎么回事)。
  • 仅供参考,3d 矩形是您删除字体真棒但不显示外壳导航更改的微调器对象的地方

标签: javascript asp.net-mvc-4 durandal hottowel


【解决方案1】:

我的主要问题是,我期望子导航菜单在没有在我的视图或视图模型中实现子导航的情况下显示。我不知道子导航不是现有导航所固有的。以下是我必须做出的改变。

通过在router.navigationModel 上添加一个带有data-bind 的元素来更改我的inventory.html 文件以充当子导航容器,该元素会拾取并显示child 导航菜单;还包括一个在router 上带有data-bind 的元素,它将在最低导航级别拾取叶节点(页面内容):

<section>
    <header>
    <h2 class="page-title" data-bind="text: title"></h2>
    <nav class="pull-left">
        <ul class="nav nav-pills nav-stacked" data-bind="foreach: router.navigationModel()">
            <li><a data-bind="    css: { active: isActive }, attr: { href: hash }, text: title" 
            href="#"></a></li>
        </ul>
    </nav>
    </header>
    <section id="inventoryPane" data-bind="router: { transition: 'entrance', cacheViews: true }"></section>
</section>

注意这里的完全导航视图实际上涉及 3 个模块。 shell.js 是具有顶级导航的根目录,然后inventory.js(例如)将是另一个带有子导航按钮的容器,最后items.js(例如)将表示显示在inventory.js 容器中的内容。

接下来,我需要更新我的 inventory.js 以充当容器,并在我对 makeRelative 的调用中指定模块的完全限定路径(在我将问题中的代码发布为许多绝望的实验之一后,我已将其删除);如果您没有正确获取 moduleId,则在尝试访问不存在对象的 router 属性时会发生致命错误,并且如果您正在运行 IE,调试器给出的消息根本没有帮助:

define(['services/logger', 'plugins/router'], function (logger, router) {
   var title = 'Inventory';
   var childRouter = router.createChildRouter()
   .makeRelative({
      moduleId: 'viewmodels/inventory',
      fromParent: true
   }).map([
         { route: 'items', moduleId: 'items', title: 'Items', nav: 3 }])
      .buildNavigationModel();
   var vm = {
      router: childRouter,
      activate: activate,
      title: title
   };

   return vm;

   //#region Internal Methods
   function activate() {
      logger.log(title + ' View Activated', null, title, true);
   }
   //#endregion
});

接下来,我似乎必须更新我的根级路由上的哈希,以避免找不到有关“*inventory”路由的错误。我不知道为什么无法更好地自动处理 splat 路线;不知何故,淘汰赛样本解决了这个问题,但我不能不覆盖哈希:

var routes = [
    { route: '', moduleId: 'home', title: 'Home', nav: 1 },
    { route: 'inventory*inventory', moduleId: 'inventory', title: 'Inventory', hash:"#inventory", nav: 2 }];

最后,我不得不重组我的树以将库存文件上移一级:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-11
    • 2015-11-09
    • 1970-01-01
    • 1970-01-01
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多