Durandal SPA接管常规网站路由

时间:2013-09-30 05:04:50

标签: javascript web-applications durandal single-page-application hottowel

我正在构建一个普通的旧网站,在其中一个页面中有一个单页应用程序。导航栏上还有其他页面,例如Home,About,Blog,我的应用程序位于仪表板中。

查看我的SPA选项后,我决定尝试Durandal,因为它似乎是我的ASP.NET网页网站最友好的。我正在使用Hot Towelette,因为它似乎是一个非常好的包,虽然我可能会切换到普通Durandal,因为我可能没有使用所有的Towelettes功能。

设置Nuget包后,我将index.cshtml更新为我的dashboard.cshtml并在导航栏上正确链接。从我的主页,我可以导航到仪表板,SPA启动并运行正常。但是,当从仪表板单击主页按钮(或博客,关于等)时,该页面只会将我返回到SPA的初始视图。

在我从index.cshtml更改后,这是我的dashboard.cshtml。我没有对从Nuget下来的Hot Towelette东西做任何其他改动。

@using System.Web
@using System.Web.Optimization
@{
    Layout = "Layout/_Layout.cshtml"; //<--- My nav bar with my other links are in here
}
<div id="applicationHost">
    @RenderPage("_splash.cshtml")
</div>

@Scripts.Render("~/scripts/vendor")
@if (HttpContext.Current.IsDebuggingEnabled)
{
    <script type="text/javascript" src="App/durandal/amd/require.js" data-main="/App/main"></script>
}

else
{
    <!-- Remember to run the Durandal optimizer.exe to create the main-built.js  -->
    <script type="text/javascript" src="App/main-built.js"></script>
}

问:如何在常规网站中设置Durandal SPA页面而不接管我所有网页的路由?

修改 这是导航部分:

//Original
<nav>
    <a href="/">Home</a> 
    <a href="aboutus">About Us</a>  
    <a href="blog">Blog</a>
</nav>

将这些更改为以下内容似乎没有任何区别。此外,它强制.cshtml扩展名进入URL,即使我使用的是FriendlyUrls。

//Ineffective Changes
<nav>
    <a href="default.cshtml">Home</a> 
    <a href="aboutus.cshtml">About Us</a>  
    <a href="blog.cshtml">Blog</a>
</nav>

5 个答案:

答案 0 :(得分:0)

我知道的唯一解决方案是将URL设置为绝对链接,如下所示:

<a href="http://www.MyGreatPage.html"></a>

但我知道并非总有可能 我会尝试回来找一些更好的解决方案。

答案 1 :(得分:0)

您没有提供与导航栏中的链接相关的任何HTML。听起来这就是问题所在。以下形式的任何链接都将触发durandal路由器:

<a href="#/dashboard">Dashboard</a>

以下表单的任何链接都将触发本机浏览器路由:

<a href="index.html">Index</a>

您能否验证这是ASP.NET编译网页源的方式?

修改

另一种选择是使用javascript导航api的点击绑定:

<a href="#" data-bind="click: function() { location.assign('index.cshtml') }">Index</a>

答案 2 :(得分:0)

也许重新考虑你的架构是最好的:

选项1:为您要创建的每个SPA制作完整的Hot Towelette项目。
选项2:反过来,您可以考虑将整个网站设为SPA 选项3:正如您所提到的,只使用Durandal而不是Hot Towelette。 (如果您不想为每个SPA创建整个项目)

<小时/> 选项4: 看看“HotTowelRouteConfig.cs”。在该文件中引用了默认控制器和操作。您可以在默认路由前加“spa”,因此结果如下:

Durandal: domain / spa /#/
(不打断你的其他路线)

选项5: 查看控制器(以“HotTowelRouteConfig.cs”命名),您可以向该控制器添加一些特定操作。

选项6: 使用带前缀的文件夹或其他内容创建一个全新的路由配置。 (选项4的反转)

Durandal:域名/#/
自定义路由:域/ pages / aboutus.cshtml

希望这有帮助。

答案 3 :(得分:0)

由于没有其他答案被接受,我想投入我的$ 0.02 -

确保动态设置的路线包含相对路径 -

 <a href="">Index</a>

你的Durandal路线是以哈希为基础的 - 请注意,此处的差异包括/

之前的哈希值
 <a href="/#index">Index</a>
 <a href="#index">Index</a>

这两项工作都被Durandal的路由器正确拦截。

对于非Durandal路线,请使用相对路径 -

 <a href="/../index">Index</a>   
 <a href="/index">Index</a>   
 <a href="/controllerName/index">Index</a>   

所有这些都应该有效,具体取决于您查看视图的方式(控制器等等)

其他可能性

在以前版本的Durandal中,如果您在同一文本中有多条结束的路线,则会找到第一条路线。如果最重要的是你有一个非Durandal路线以相同的文字结尾,它可能也可能做同样的事情。解决方法是使用guardRoute确保仅拦截正确的路由。

有两件事你可以试着看看是否发生了这种情况 -

router.mapUnknownRoutes(function(instruction){
    console.log(instruction);
    if (instruction.fragment === 'index.cshtml') {
         window.location('/' + instruction.fragment);
    }
});

在激活第一条路线之前,在main.js或您拥有的任何入口点注册该处理程序,它应该捕获任何未知路线。在那一点上,检查指令的某些部分(在控制台中查看它包含的内容的更好细分)是否与.cshtml匹配,如果是,则构建正确的URI字符串和window.location它。

这将允许您覆盖错误的路由,可能会将它们指向自定义错误页面。

答案 4 :(得分:0)

由于没有其他选项适合我,最终我的解决方案是切换到Sammy.js。我能够以接近零的努力将Sammy.js放入我现有的应用程序中,并且它与我网站的其他部分没有冲突。作为额外的奖励,Sammy的路由不会触发完整导航,这意味着在使用Sammy.js导航时全屏应用程序将保持全屏。