使用ASP.Net MVC RouteConfig的AngularJS Ui-Router。 它是如何工作的?

我正在阅读这篇文章 ,我仍然无法理解Angular的UI路由器如何使用ASP.Net路由。

有人能够以简单明了的方式解释从手动输入URL到浏览器的整个生命周期(例如: http:// myapp / stateOne )。 谁处理请求,ASP.Net? 如果没有,如果页面由ASP提供,在它可以介入之前,角度如何拦截URL请求? AngularJS何时加入州提供商?

我对此非常困惑,对这个想法找不到多少。

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

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

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

HTML5模式正在运行,但只是以一种非常肤浅的方式。 刷新页面是将完整的URL发送到服务器(因为我们已经删除了苏格兰威士忌),它不知道该怎么做。 我们可以通过正确地重新配置MVC的RouteCollection来解决这个问题。 我们需要明确每个视图的路径,然后添加一个catch-all,将所有其他URL发送到我们的登录页面,由Angular处理。

更新App_Start => RouteConfig.cs中的RegisterRoutes方法,如下所示:

 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" }); } 

快乐的路径生命周期

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

客户端路由

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

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

完全重新加载根URL将加载主索引内容,重新初始化角度应用程序并选择相应的客户端路由(在这种情况下将是与该路由关联的登录路由和模块)。 但是,一旦你偏离了这一点,就会遇到不愉快的路径问题。

不开心的道路

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

其他问题

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

这可能是什么样的

您可能希望声明一个处理默认入口点的路径:

 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:

      

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 }) });