0

当想要在路由器中设置的路由列表之外导航时,如何逃避客户端路由?

我使用 Durandal.js 创建了一个项目,并在不同的区域内创建了 SPA。我遇到的问题是,当我想在当前 SPA 之外导航并进入另一个或说回到整个应用程序的主页时,这根本不是 SPA,而只是一个 cshtml 页面。

我试图做的是使用 Durandal 的 mapUnknownRoutes 处理程序进行拦截,然后使用 window.location.href 导航出去。这可行,但是当我想进入应用程序的主页(“/”)时,路由器会匹配 SPA 的“根”并且不会导航到主页,而是导航到 SPA 的根路由。

此示例中的区域路由是“/spaHome”,其 MVC 路由如下所示:

context.MapRoute(
           "spaHome_default",
           "spaHome/{*catchall}",
           new { controller = "Home", action = "Index", id = UrlParameter.Optional }
       );

这是我为设置 Durandal 路由器所做的工作:

var routes = [
    { route: ['spaHome', ''], moduleId: 'spaHome', title: "spaHome", hash: "#spaHome"},
    { route: 'one/anotherPage', moduleId: 'one/anotherPage', title: "one/anotherPage", hash: "#one/anotherPage"}
];

router.makeRelative({ moduleId: 'viewmodels' });

router.map(routes)
      .mapUnknownRoutes(function (instruction) {
          utils.navigateToPath(instruction.fragment);
          return false;
      })
      .activate({ pushState: true, root: "/spaHome" });

任何指向正确方向的指针或线索将不胜感激!

4

1 回答 1

0

经过一些试验和错误,我能够想出一个解决方案来解决我正在尝试完成的事情。它看起来像一个可靠的解决方案,所以希望它不会在未来造成任何问题。

我更改了路由数组并从第一条路由中删除了默认路由“”。当我想要访问正常的 MVC 主页时,这让我有一条未知的路线可以离开。我还必须从路由器的激活功能中删除“根”属性。这反过来意味着我必须使用额外区域部分或 URL(“spaHome/”)显式声明路由数组中的路由。

然后在我的 mapUnknownRoutes 处理程序中,我检查了 URL 区域部分的路由,如果存在,我使用 SPA 路由器显示该 SPA 的未找到页面。否则,我假设该路线存在于该区域之外,我需要使用 window.location.href 硬导航到 URL。

var routes = [
    { route: ['spaHome'], moduleId: 'spaHome', title: "spaHome", hash: "#spaHome"},
    { route: 'spaHome/one/anotherPage', moduleId: 'one/anotherPage', title: "one/anotherPage", hash: "#spaHome/one/anotherPage"}
];

router.makeRelative({ moduleId: 'viewmodels' });

router.map(routes)
  .mapUnknownRoutes(function (instruction) {
      if (instruction.fragment.toLowerCase().indexOf("spaHome/", 0) === -1) {
            utils.navigateToPath(instruction.fragment);
      } else {
            var notfoundRoute = "notfound";
            instruction.config.moduleId = notfoundRoute;
            history.navigate(notfoundRoute, { trigger: false, replace: true });
      }
  })
  .activate({ pushState: true });

如果有人有更好的解决方案,请告诉我!


编辑

好的,我在执行此操作时遇到了历史问题。我必须在 Durandal router.js 文件中添加一行,以阻止将先前的路由添加到历史队列中。

 if (!instruction.cancelQueue) {
                router.trigger('router:route:before-config', instruction.config, router);
                router.trigger('router:route:after-config', instruction.config, router);
                queueInstruction(instruction);
            }

编辑 2

我还遇到了这种方法的问题,即导航不适用于 IE9 及以下版本。

于 2016-11-18T18:55:51.233 回答