问题描述
我正在阅读 这篇文章,我仍然无法理解 Angular 的 UI 路由器如何与 ASP.Net 路由一起工作.
I'm reading this article and I still can't get around my head on how Angular's UI Router is working with ASP.Net routing.
有人可以简单明了地解释一下从手动将 URL 输入浏览器开始的整个生命周期(例如:http://myapp/stateOne ).谁处理请求,ASP.Net?如果没有,如果页面由 ASP 提供服务,Angular 如何在它介入之前拦截 URL 请求?AngularJS 什么时候加入状态提供者?
Can someone explain in an easy and clear way, the full life cycle from when a URL is typed into the browser manually (ex: http://myapp/stateOne ). Who handles the request, ASP.Net? If not, how does angular intercept a URL request if the page is being served by ASP before it can step in? And when does AngularJS come in with the state provider?
我对此很困惑,找不到太多关于这个想法的信息.
I'm very confused on this and can't find much on the idea.
除了这个问题,我还有一些我无法理解的事情.我正在编写一个应用程序,其中:
In addition to the question, I have a couple of other things I can't understand. I'm writing an app where:
- Home/Index.cshtml -> 着陆页根据状态提供内容(例如:它有一个 ui-view="content",例如,它应该反过来提供 Categories/Index.cshtml).那么,我将如何设置默认状态",以便导航到索引会加载主页和带有默认类别的 ng-view 内容?
- Login/Index.cshtml -> 我使用 modal.show() 和 modal.hide() 隐藏和显示的模态表单.从 ui 视图提供.这是有效的.但是,如果用户键入 http://myapp/login 我该怎么办?我可以以某种方式拦截请求并显示带有打开模式表单的索引页面吗?或者甚至更好,当前页面并打开模态表单?(即:是否可以在没有 templateURL 的情况下设置状态)?
- 如果我有一个包含多个列表的页面怎么办?例如,我已经看到人们将状态设置为 state.childState,但是如果我需要一次加载多个列表(因此,多个状态-> 视图)怎么办?
- Home/Index.cshtml -> Landing page serves content based on states (ie: it has a ui-view="content", which should in turn serve Categories/Index.cshtml in it, for example). So, how would I go around setting the "Default state" so that navigating to index would load the home page and the ng-view content with default categories in it?
- Login/Index.cshtml -> A modal form which I'm hiding and showing using modal.show() and modal.hide(). Served from a ui-view. This is working. However, if the user types http://myapp/login what should I do? Can I somehow intercept the request and show the index page with the open modal form in it? or even better, the current page and just open up the modal form? (ie: Is it possible to set a state without a templateURL)?
- What if I have a page which has multiple lists in it? I've seen people set the state to state.childState for instance, but what if I need to load multiple lists (and therefore, multiple states-> views) at once?
编辑:特别注意这部分,如果我理解正确,它使用黑魔法使 routeTwo/6
加载索引页面,并将 routeTwo 页面加载到 UI-View 中.
Edit:Special attention to this part, which uses black magic to cause routeTwo/6
to load the index page with the routeTwo page loaded in a UI-View if I'm understanding correctly.
HTML5 模式是有效的,但只是以一种非常肤浅的方式.刷新页面正在向服务器发送完整的 URL(因为我们已经删除了苏格兰威士忌),它不知道该怎么做.我们可以通过正确地重新配置 MVC 的 RouteCollection.我们需要明确关于我们每个视图的路线,然后添加一个包罗万象的将所有其他 URL 发送到我们的着陆页,由 Angular 处理.
更新 App_Start 中的 RegisterRoutes 方法 => RouteConfig.cs像这样:
Update the RegisterRoutes method inside App_Start => RouteConfig.cs like so:
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" });
}
推荐答案
Happy Path Lifecycle
- 向服务器发出请求,因为客户端在从 URL 请求内容时尚未加载任何资源.ASP.NET 路由接收请求并返回为该路由绑定的任何内容.
- 如果返回索引(包含 AngularJS 应用程序的入口点,则从服务器加载 HTML 内容和后续资源.
- AngularJS 在收到 DOM 就绪事件后运行
- AngularJS 解析 DOM 并开始执行它遇到的各种组件.
客户端路由
一旦您的应用程序加载完毕,客户端路由模块(如 ui-router ngRoute 或新的组件路由器)将为您控制路由并加载绑定到该路由的内容.但是,这只有在您始终维护用于引导 Angular 应用程序的预定义根路由时才能正常工作.
Once your application has loaded, client-side routing modules like ui-router ngRoute or the new component router will control the route for you and load content that is bound to that route. However, this only works properly if you always maintain to a pre-defined root route that you use to bootstrap your Angular application.
I.E.www.site.com/Home#/login
或 www.site.com/Home!/login
如果使用 $locationProvider.hashPrefix('!').html5Mode(true);
.
I.E. www.site.com/Home#/login
or www.site.com/Home!/login
if using $locationProvider.hashPrefix('!').html5Mode(true);
.
完全重新加载您的根 URL 将加载您的主索引内容,重新初始化 angular 应用程序并选择相应的客户端路由(在这种情况下将是登录路由和与该路由关联的模块).然而,一旦你偏离了这一点,你就会遇到不愉快的路径问题.
Fully reloading your root URL will load your main index content, re-initialize the angular application and pick up the corresponding client-side routing (which in this case would be the login route and module associated with that route). However, once you deviate from this, you run into unhappy path concerns.
不幸之路
如果您请求的 URL 不返回 AngularJS 应用程序的入口点,Angular 无法拦截该请求,因此将永远不会运行.因此,如果请求的 URL 不是 Angular 应用程序的入口点,则您必须决定如何处理它.一种常见的方法是重定向到索引.
If you request a URL that does NOT return the entrance point to the AngularJS application, Angular has no way to intercept the request and, subsequently will never run. As a result, if a request is being made to a URL that is not the entrance point to the Angular application, you have to decide how you want to handle it. A common approach is to redirect to Index.
其他问题
- Home/Index.cshtml - 由于您正在混合两个世界,我建议允许 Angular 在加载后控制和驱动所有导航.这将包括调用部分路由和加载 razor 视图,就好像它们是模板一样(如果您想继续使用 Razor).
- Login/Index.cshtml - 这真的很棘手.一种选择是检测他们是否从 Ajax 调用此路由.如果是,则允许请求.如果没有,请重定向回索引,因为它们正在执行整页加载.另一种选择是提供整个 url,但您需要确保您的 angular 应用程序入口点也已交付.然后,您可以在加载 angular 应用程序以加载主页内容后使用一些魔法,然后再弹出模态.但是,一旦遇到这种性质的其他情况,这很快就会变得混乱.
- 如果我有一个包含多个列表的页面怎么办?- 你会同时显示多个列表吗?如果是这样,那很好,因为您实际上可以加载一个父状态/模板/控制器,然后包含额外的子模板/控制器,而无需更改父状态.但是,这个问题非常广泛和复杂,确实需要作为一个单独的具体问题.
这可能是什么样子
您需要声明一条处理默认入口点的路线:
You would want to declare a route that handles your default entrance point:
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
This way, if a user hit www.site.com
, we would return the content from /Home/LoadMain. This content would include all of our required Angular references (Angular, UI-Router, our main app, etc), which would then allow us to default our client-side route to /home and subsequently load /Home/Index
Main.cshtml:
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
})
});
这篇关于带有 ASP.Net MVC RouteConfig 的 AngularJS Ui-Router.它是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!