【问题标题】:AngularJS and MVC RoutingAngularJS 和 MVC 路由
【发布时间】:2015-04-02 23:18:56
【问题描述】:

我一直在做很多关于在 MVC 上使用 AngularJS 实现 SPA 的研究,但我认为我遗漏了一些东西。我是否仍然需要为每个 View 使用 MVC 控制器,或者 Angular 是否应该能够在没有 MVC 控制器的情况下抓取 cshtml 或 html 文件以在初始页面上呈现?

基本上我有

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

返回我的索引页面,它只是

<div data-ng-view></div>

它还加载了一个带有索引页面的布局,该页面上有我的菜单以及所有链接以及所有脚本文件。当我点击如下链接时:

<a href="/Home/ChangeLog">Change Log</a>

其中包含

<h2>{{Changes.Title}}</h2>
<div>{{Changes.Version}}</div>

它无法加载任何内容,因为它正在尝试访问 MVC 控制器。如果我有一个返回局部视图的 MVC 控制器,它只会将局部视图作为整个页面加载返回。我的角度应用文件是这样的:

var myApp= angular.module("myApp.WebConsole", ['ngRoute']);

myApp.controller("IndexController", IndexController);

var configFunction = function ($routeProvider, $locationProvider, $httpProvider) {

$routeProvider.when("/Home/Index",
    {
        templateUrl: "Home/Index.cshtml",
        controller: IndexController
    });

$routeProvider.when("/Home/ChangeLog",
    {
        templateUrl: "Home/ChangeLog.cshtml",
        controller: IndexController
    });
$locationProvider.html5Mode(true);
}

configFunction.$inject = ["$routeProvider", "$locationProvider", "$httpProvider"];

myApp.config(configFunction);

而indexcontroller.js文件是:

var IndexController = function ($scope) {
    $scope.Heading = "Index Page";
    $scope.Changes = {
        Title: "Changes",
        Version: "1.0"
    };
}

IndexController.$inject = ['$scope'];

js 文件位于单独的文件夹中。视图位于标准 MVC 文件夹结构中。

我对它的工作原理有什么遗漏?我希望单击该链接将检索 cshtml 文件,甚至只是一个 html 文件,并在 div 中呈现带有 data-ng-view 标签的 html。我是否应该不使用 Razor 视图(可能是问题的一部分,因为我希望 MVC 控制器需要渲染代码数据,如果有的话)?虽然如果我只使用 html,我仍然会遇到同样的问题,即找不到页面。

编辑2:好的,所以我已经部分弄清楚了,问题在于使用

$locationProvider.html5Mode(true);

没有这个,如果我在菜单上创建链接

<a href="/#/Home/ChangeLog">Change Log</a>

然后一切似乎都正常。我相信这也是使用 Angular 的链接的预期格式。在启用 html5Mode 的情况下制作 MVC 和 Angular 路由有什么魔力吗?

【问题讨论】:

  • 仅供参考:我总是将所有 AngularJS 的东西(脚本 + htmls)放到一个文件夹中,比如 /app,然后在该文件夹上执行 IgnoreRoute。我不想通过启动 ASP.NET MVC 并返回部分视图来为 Angular 提供一些 HTML。

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


【解决方案1】:

您想使用更像Home/Index#/Changelog 的东西——MVC 路由在索引处停止,而 Angular 在# 之后“拾取”。

如果你搜索“mvc angular routing”有很多例子,但就是这样。

【讨论】:

    【解决方案2】:

    您是对的,问题是您使用的是 html5mode(true),它不会使用 # url,因此会首先向服务器发出浏览器请求。如果您想继续使用 html5mode=true,您需要强制 ASP.NET MVC 将所有这些 angular url 指向同一页面(您的 angular 应用程序主页)。然后当页面在客户端加载时,角度路由将接管并路由到正确的视图。

    您可以这样做的一种方法是使用“笼统”的 MVC 路由。
    假设您的 Angular 应用程序在 /Home/Index 启动,请编辑您的 RouteConfig.RegisterRoutes 方法并添加此路由:

    routes.MapRoute(name: "My angular webapp",
    url: "Home/{*catchall}",
    defaults: new { controller = "Home", action="Index", id=UrlParameters.Optional }
    );
    

    这将使所有对 /Home/anything 的请求都返回 Home/Index 视图。因此,您可能希望为您的 Angular 应用程序使用另一个控制器,以防您希望 MVC 处理 Home 下的其他 url。

    【讨论】:

    • 所以我在这里看到了这个解决方案:link 但我得到了一些奇怪的结果。当我单击链接中说明的现在为 的链接时,我会得到我认为每次将“home/changelog”附加到 url 的预期结果我点击它,所以最终你会得到 /home/home/home/home/changelog。发生这种情况时没有错误,但没有从模板页面加载数据。
    • 如果我使用 url 形成是好的,但我仍然没有返回到页面的数据。似乎每次点击使用这种方法都会导致整个页面加载,因为基本上每次点击 Angular 控制器都会真正进入服务器并被重定向回 Home/Index。似乎它破坏了 SPA 的意义?
    • 该链接基本上暗示了我所做的,只是在不同的控制器下。 Angular 应该拦截点击,并且当人们只是在使用该站点时不会进行服务器调用。但是,与其他网站一样,深度链接到您的 Angular 路由会访问服务器,这就是为什么您在 MVC 中拥有包罗万象的路由。也不是每个浏览器都支持 html5 导航模式,例如 IE9,所以它们每次都会访问服务器。
    猜你喜欢
    • 1970-01-01
    • 2014-11-22
    • 1970-01-01
    • 2017-06-10
    • 1970-01-01
    • 2015-05-15
    • 2014-12-09
    • 2016-05-26
    • 1970-01-01
    相关资源
    最近更新 更多