代码之家  ›  专栏  ›  技术社区  ›  Dragonseer

Durandal SPA接管常规网站路由

  •  2
  • Dragonseer  · 技术社区  · 11 年前

    我正在构建一个简单的旧网站,它的一个页面中有一个单页应用程序。导航栏上还有其他页面,如主页、关于、博客,我的应用程序位于仪表板中。

    在浏览了我的SPA选项后,我决定尝试Durandal,因为它似乎是我的ASP.NET网页网站最友好的。我正在使用Hot Towelette,因为它看起来是一个非常好的包,尽管我可能会改用普通的Durandal,因为我可能不会使用Towelette的所有功能。

    在设置了Nuget包之后,我将index.cshtml更新到我的dashboard.cshtml,并在导航栏上适当地链接它。从我的主页,我可以导航到仪表板,SPA开始运行并运行良好。然而,当单击仪表板上的主页按钮(或博客、about等)时,页面会将我返回到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>
    }
    

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

    编辑 这是导航部分:

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

    将这些更改为以下内容似乎没有什么区别。此外,即使我使用的是FriendlyUrls,它也会强制将.cshtml扩展名添加到URL中。

    //Ineffective Changes
    <nav>
        <a href="default.cshtml">Home</a> 
        <a href="aboutus.cshtml">About Us</a>  
        <a href="blog.cshtml">Blog</a>
    </nav>
    
    5 回复  |  直到 11 年前
        1
  •  0
  •   Rocky Balboa    11 年前

    我知道的唯一解决方案是使链接中的url绝对化,所以类似于:

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

    但我知道这并不总是可能的。
    我会试着回来找一些更好的解决方案。

        2
  •  0
  •   Matthew James Davis    11 年前

    您没有提供任何与导航栏中的链接相关的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>
    
        3
  •  0
  •   Cory Silva    11 年前

    也许重新思考您的架构是最好的:

    选项1: 为您打算创建的每个SPA制作完整的热毛巾项目。
    选项2: 相反,你可以考虑将整个网站打造成一个SPA。
    选项3: 只要使用杜兰达尔,而不是你提到的热毛巾。 (如果您不想为每个SPA创建一个完整的项目)


    选项4: 看看“HotTowelRouteConfig.cs”。在该文件中引用了一个默认的控制器和操作。您可以在默认路线前面加上“spa”,这样结果会是:

    杜兰达尔: 域名/spa/#/
    (不要打断你的其他路线)

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

    选项6: 创建一个带有前缀的文件夹或其他东西的全新路由配置。 (与选项4相反)

    杜兰达尔: 领域/#/
    自定义路线: 域/页面/aboutus.cshtml

    希望这能有所帮助。

        4
  •  0
  •   PW Kad    11 年前

    由于其他答案都没有被接受,我想投入0.02美元-

    确保正在动态设置的路线包括相对路径-

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

    而且你的杜兰达尔路线是基于哈希的- 请注意,这里的区别在于在/

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

    这两者都能正常工作,并被杜兰达尔的路由器正确拦截。

    对于非杜兰达尔路线,请使用相对路径-

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

    所有这些都应该有效,这取决于您如何定位视图(控制器等)

    其他可能性

    在之前的杜兰达尔版本中,如果你有多条路线 结束了 在同一文本中,它会找到第一个。除此之外,如果你有一条以相同文本结束的非杜兰达尔路线,它可能也会这样做。修复方法是使用guardRoute来确保只拦截正确的路由。

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

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

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

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

        5
  •  0
  •   Dragonseer    11 年前

    由于没有其他选择对我有效,最终我的解决方案是切换到Sammy.js。我可以毫不费力地将Sammy.jss放入我现有的应用程序中,而且它与我网站的其他部分没有冲突。此外,Sammy的路由不会触发完全导航,这意味着全屏应用程序在使用Sammy.js导航时将保持全屏状态。