【问题标题】:AngularJS Ui-Router with ASP.Net MVC RouteConfig. How does it work?AngularJS Ui-Router 与 ASP.Net MVC RouteConfig。它是如何工作的?
【发布时间】:2015-12-10 23:06:03
【问题描述】:

我正在阅读 this article,但我仍然无法理解 Angular 的 UI 路由器如何与 ASP.Net 路由一起工作。

有人可以简单明了地解释从手动将 URL 输入浏览器的整个生命周期(例如:http://myapp/stateOne)。谁处理请求,ASP.Net?如果不是,如果页面在 ASP 提供服务之前它可以介入,那么角度如何拦截 URL 请求? AngularJS 什么时候与状态提供者一起出现?

我对此很困惑,找不到太多关于这个想法的信息。

除了这个问题,我还有其他一些我无法理解的事情。我正在编写一个应用程序:

  • Home/Index.cshtml -> 登陆页面根据状态提供内容(例如:它有一个 ui-view="content",例如,它应该反过来提供 Categories/Index.cshtml)。那么,我该如何设置“默认状态”,以便导航到索引会加载主页和 ng-view 内容,其中包含默认类别?
  • Lo​​gin/Index.cshtml -> 我使用 modal.show() 和 modal.hide() 隐藏和显示的模态表单。从 ui 视图提供。这是有效的。但是,如果用户输入http://myapp/login,我该怎么办?我可以以某种方式拦截请求并显示带有打开模式表单的索引页面吗?甚至更好的是,当前页面只是打开模态表单? (即:是否可以在没有 templateURL 的情况下设置状态)?
  • 如果我的页面中有多个列表怎么办?例如,我见过有人将状态设置为 state.childState,但是如果我需要一次加载多个列表(因此,多个状态-> 视图)怎么办?

编辑: 特别注意这部分,如果我理解正确的话,它使用黑魔法使routeTwo/6 加载 index 页面,并在 UI-View 中加载 routeTwo 页面。

HTML5 模式正在工作,但只是以一种非常肤浅的方式。刷新 的页面正在向服务器发送完整的 URL(因为我们已删除 苏格兰威士忌)不知道该怎么办。我们可以通过 正确重新配置 MVC 的 RouteCollection。我们需要明确 关于我们每个视图的路线,然后添加一个包罗万象的 将所有其他 URL 发送到我们的着陆页,由 Angular 处理。

更新 App_Start 中的 RegisterRoutes 方法 => RouteConfig.cs 像这样:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "routeOne",
        url: "routesDemo/One",
        defaults: new { controller = "RoutesDemo", action = "One" });

    routes.MapRoute(
        name: "routeTwo",
        url: "routesDemo/Two/{donuts}",
        defaults: new { controller = "RoutesDemo", action = "Two", donuts = UrlParameter.Optional });

    routes.MapRoute(
        name: "routeThree",
        url: "routesDemo/Three",
        defaults: new { controller = "RoutesDemo", action = "Three" });

    routes.MapRoute(
        name: "login",
        url: "Account/Login",
        defaults: new { controller = "Account", action = "Login" });

    routes.MapRoute(
        name: "register",
        url: "Account/Register",
        defaults: new { controller = "Account", action = "Register" });

    routes.MapRoute(
        name: "Default",
        url: "{*url}",
        defaults: new { controller = "Home", action = "Index" });
}

【问题讨论】:

    标签: c# asp.net .net angularjs asp.net-mvc


    【解决方案1】:

    快乐路径生命周期

    1. 向服务器发出请求,因为客户端在从 URL 请求内容时尚未加载任何资源。 ASP.NET 路由选择请求并返回绑定到该路由的任何内容。
    2. 如果返回索引(包含 AngularJS 应用程序的入口点,则从服务器加载 HTML 内容和后续资源。
    3. AngularJS 在收到 DOM 就绪事件后运行
    4. AngularJS 解析 DOM 并开始执行它遇到的各种组件。

    客户端路由

    一旦您的应用程序加载完毕,客户端路由模块(如 ui-router ngRoute 或新的组件路由器)将为您控制路由并加载绑定到该路由的内容。但是,只有在您始终维护用于引导 Angular 应用程序的预定义根路由时,这才能正常工作。

    I.E. www.site.com/Home#/loginwww.site.com/Home!/login 如果使用 $locationProvider.hashPrefix('!').html5Mode(true);

    完全重新加载您的根 URL 将加载您的主索引内容,重新初始化 Angular 应用程序并获取相应的客户端路由(在本例中为登录路由和与该路由关联的模块)。但是,一旦偏离这一点,就会遇到不愉快的路径问题。

    不愉快的道路

    如果您请求的 URL 不返回 AngularJS 应用程序的入口点,Angular 将无法拦截该请求,并且随后将永远不会运行。因此,如果向不是 Angular 应用程序入口点的 URL 发出请求,您必须决定如何处理它。一种常见的方法是重定向到索引。

    其他问题

    • Home/Index.cshtml - 由于您正在融合这两个世界,我建议允许 Angular 在加载后控制和驱动所有导航。这将包括调用部分路由和加载 razor 视图,就好像它们是模板一样(如果你想继续使用 Razor)。
    • Lo​​gin/Index.cshtml - 这真的很棘手。一种选择是检测他们是否从 Ajax 调用此路由。如果是,请允许该请求。如果没有,请重定向回索引,因为它们正在执行整页加载。另一种选择是提供整个网址,但您需要确保您的角度应用程序入口点也已交付。然后,您可以在加载 Angular 应用程序以加载主页内容后使用一些魔法,然后弹出模式。但是,一旦遇到这种性质的其他情况,这很快就会变得混乱。
    • 如果我的页面中有多个列表怎么办? - 你会同时显示多个列表吗?如果是这样,那很好,因为您实际上可以加载父状态/模板/控制器,然后包含其他子模板/控制器,而无需更改父状态。但是,这个问题非常广泛和复杂,确实需要一个单独的具体问题。

    这可能是什么样子

    你会想要声明一个处理你的默认入口点的路由:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "LoadMain", id = UrlParameter.Optional }
        );
    }
    
    public class HomeController : Controller
    {
        public ActionResult LoadMain()
        {
            return View("Main.cshtml");
        }
    }
    
    public class CategoriesController : Controller
    {
        public ActionResult Index()
        {
            return PartialView("Index.cshtml");
        }
    }
    

    这样,如果用户点击www.site.com,我们将从/Home/LoadMain 返回内容。该内容将包括我们所有必需的 Angular 引用(Angular、UI-Router、我们的主应用程序等),然后允许我们将客户端路由默认为 /home 并随后加载 /Home/Index

    Main.cshtml:

    <head>
        <script src="//angular.js"></script>
        <script src="//angular-ui-router.min.js"></script>
        <script src="app.js"></script>
    <body ng-app="app">
        <div ui-view></div>
    </body>
    

    app.js

    var app = angular.module('app', ['ui.router']);
    app.config(function($stateProvider, $urlRouterProvider) {
    
        $urlRouterProvider.otherwise('/home');
    
        $stateProvider
            .state('home', {
                url: '/home',
                templateUrl: '/Categories/Index' // corresponds to an MVC partial route
            })
            .state('login', {
                url: '/login',
                templateUrl: '/Login/Index' // corresponds to an MVC partial route
            })
        });
    

    【讨论】:

    • 你已经清理了很多,谢谢!同意第三点(附加问题)。关于If you request a URL that does NOT return the entrance point to the AngularJS application -> 所以唯一的入口点是 Home/Index.cshtml 对吗?我可以指定额外的“入口点”吗?它们是从 ASP.Net RouteConfig、角度状态提供程序还是两者中指定的?
    • $locationProvider.hashPrefix('!').html5Mode(true); 应该处理哈希(但我可能错了)。所以澄清一下,一旦加载了 Angular,如果用户输入了 site.com/Login,它会神奇地加载提供内容的索引页面,然后在其中提供 /Login 模板 URL?
    • 至于您的入口点,从技术上讲,您可以将入口点设为始终加载的共享视图,这意味着每次完整的 url 加载都会加载 Angular 应用程序。但是,这将在未来产生其他问题,例如将模态加载为 Angular 应用程序的整页 html ......这没有任何意义。谨慎选择有限数量的入口点或为每个入口点构建单独的 Angular 应用程序并高度模块化您的应用程序会更安全、更明智,尽管这可能有点矫枉过正
    • 有趣。所以任何时候重新加载页面都会重定向到首页?
    • 正确,只要您对有限的 IE 支持没问题,您就可以使用 html5 模式而不是哈希。但是,您的 url 示例不正确。您实际上希望让您的用户访问 site.com/!/Login 或拦截请求并将其重定向到 site.com/!/Login 以确保最小的入口点。
    猜你喜欢
    • 2015-02-22
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 2012-12-31
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多