繁体   English   中英

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

[英]AngularJS Ui-Router with ASP.Net MVC RouteConfig. How does it work?

我正在读这篇文章 ,我仍然无法理解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 ,我该怎么办? 我可以以某种方式拦截请求并显示带有开放模式形式的索引页面吗? 甚至更好,当前的页面,只是打开模态窗体? (即:是否可以设置没有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调用此路由。 如果是,请允许请求。 如果没有,则重定向回索引,因为它们正在执行整页加载。 另一种选择是提供整个网址,但您需要确保您的角度应用入口点也已交付。 然后,在加载角度应用程序以加载主页面内容后,您可以使用一些魔法,然后再弹出模态。 但是,一旦你有这种性质的其他情况,这很快就会变得混乱。
  • 如果我有一个包含多个列表的页面怎么办? - 你会一次显示多个列表吗? 如果是这样,那很好,因为您实际上可以加载父状态/模板/控制器,然后包含其他子模板/控制器,而无需更改父状态。 然而,这个问题非常广泛和复杂,实际上需要一个单独的,具体的问题。

这可能是什么样的

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM