【问题标题】:AngularJS + ASP.NET MVC - Can you use both under "/"?AngularJS + ASP.NET MVC - 你可以在“/”下同时使用吗?
【发布时间】:2014-02-24 21:08:01
【问题描述】:

我想从“/”提供我的 AngularJS SPA,因此我禁用了默认路由并正在使用

    // this action does not 'fire' due to Angular's routing...
    routes.MapRoute(
        name: "Test",
        url: "Test",
        defaults: new { controller = "Home", action = "Test" },
        namespaces: new[] { "My.WebApp.Controllers" }
    );

    // Index view has no layout and contains Angular SPA
    routes.MapRoute(
        name: "AngularJs-SPA",
        url: "{*catchall}",
        defaults: new { controller = "Home", action = "Index" },
        namespaces: new[] { "My.WebApp.Controllers" }
    );

我也在使用以下 Angular 应用程序配置块

  .config(['$routeProvider', '$httpProvider', '$locationProvider', function ($routeProvider, $httpProvider, $locationProvider) {

      $routeProvider.otherwise({ redirectTo: '/404' });
      $httpProvider.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
      $locationProvider.html5Mode(true);
  }])

我的问题是,我还能以某种方式拥有一个响应 MVC 操作的常规服务器端页面(在本例中为 /Home/Test)吗? 我看到的问题是 Angular 接管了路由,即使我定义了额外的路由(在 Angular 路由之前或之后),Angular 也将其视为“否则”路由......

很少(不受欢迎的)解决方案

  • 在 MVC 中指定每个 Angular 应用程序路由,而不是 {*catchall}
  • 将 angular spa 移动到非 root 操作(例如 /app)

【问题讨论】:

    标签: asp.net-mvc angularjs asp.net-mvc-routing single-page-application angularjs-routing


    【解决方案1】:

    您可以直接从otherwise 设置$window.location:

    myApp
        .config(function($routeProvider, $locationProvider) {
            $routeProvider
                .when("/", {
                    template: "<h1>Welcome!</h1>"
                })
                .otherwise({
                    template: " ",
                    controller: function($location, $window) {
                        $window.location.href = $location.path();
                        return false;
                    }
                });
            $locationProvider.html5Mode(true);
        });
    

    【讨论】:

    • 我试过这个,它会导致“无限循环”,而页面 /Home/Test 不断被加载 200 OK....
    【解决方案2】:

    这可能不是您想要的,但现在我正在这样做,而且效果很好。

    在 .config 中注意我正在执行 html5Mode(false)。这使 URL 保持在同一页面上,并添加了 /# 以防止 MVC 路由器接管。这也意味着您需要在链接中添加 /# 以确保您可以为页面添加书签并返回(通过服务器端路由)。

    另外,由于 MVC 路由器成群结队页面并限制对 CSHTML 文件的访问,我正在使用服务器端方法来获取 html 部分视图。其中一些视图使用 HTML Helpers,因此我将它们保留为 CSHTML 文件,而不是将它们放在不受限制的静态视图箱中。

    MVC 路由

            routes.MapRoute(
                name: "Direct",
                url: "{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
    
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
    

    -- Home(或基本)控制器中的方法

        public PartialViewResult GetPartial(string p)
        {
            return PartialView(string.Format("~/Views/Home/Partials/{0}.cshtml", p));
        }
    

    -- Angular 代码

    app.config(function ($routeProvider, $locationProvider) {
        $locationProvider.html5Mode(false);
    
        $routeProvider
            .when("/", { templateUrl: "/GetPartial?p=Dashboard", controller: "DashboardController" })
            .when("/NewWidget/", { templateUrl: "/GetPartial?p=NewWidget", controller: "NewWidgetController" })
            .when("/Widget/:widgetId", { templateUrl: "/GetPartial?p=Widget", controller: "WidgetController" })
            .when("/Widget/Edit/:widgetId", { templateUrl: "/GetPartial?p=WidgetEdit", controller: "EditWidgetController" })
            .otherwise({ redirectTo: "/" });
    
    });
    
    app.controller('DashboardController', function ($scope, $http, $timeout, $q, $sce, $location, $routeParams) {
    
        $scope.SetPath = function (route) {
                if (!route) return;
    
                route = route.replace('/#', '');
    
                if (route[0] == '/')
                    $location.path(route);
                else
                    $location.path('/' + route);
            };
    });
    

    -- HTML

    选项 A)

    <a ng-click="SetPath('/Widget?widgetId=w1234')">View Widget 1234</a>
    

    选项 B)

    <a href="/#/Widget?widgetId=w1234">View Widget 1234</a>
    

    【讨论】:

    • “请注意 .config 中我正在执行 html5Mode(false)”...不幸的是,这对我来说是个大问题...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-18
    • 2011-02-05
    • 2010-09-07
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    相关资源
    最近更新 更多