如何在ASP.NET MVC中定义角度路由

时间:2016-09-12 15:22:39

标签: javascript asp.net angularjs asp.net-mvc angular-routing

我对在Asp.Net MVC应用程序中使用Angular的路由感到有点困惑。

要了解我的问题,我会显示我的应用的当前代码:

Index.cshtml:

<head>
    ...
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
</head>
<body>
    <div class="navbar navbar-default navbar-fixed-top">
        <div class="container">
            <div class="navbar-collapse collapse glyphicons pull-right">
                <ul class="nav navbar-nav">
                    <li ng-class="{active:isActive == '/test1'}">
                        <a href="#/test1">Test1</a>
                    </li>
                    <li ng-class="{active:isActive == '/test2'}">
                        <a href="#/test2">Test2</a>
                    </li>
                </ul>
            </div>
        </div>
    </div>
    <div class="container body-content">
        <div ng-view></div>
    </div>

    @Scripts.Render("~/bundles/angular")
    @Scripts.Render("~/bundles/app")
</body>

HomeController(ASP.NET):

namespace Tests.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return PartialView();
        }

        public ActionResult Test1()
        {
            return PartialView();
        }

        public ActionResult Test2()
        {
            return PartialView();
        }
    }
}

我的Angular模块:

angular
   .module('Tests', [
      'ngRoute'
   ])
   .config(config)
   .run(['$rootScope', '$route', '$location', function($rootScope, $route, $location) {
      $rootScope.$on('$routeChangeSuccess', function(event, currRoute, prevRoute) {
         $rootScope.title = $route.current.title;
      });

      var path = function() {
         return $location.path();
      };

      $rootScope.$watch(path, function(newPath, oldPath) {
         $rootScope.isActive = newPath;
      });
   }]);

config.$inject = ['$routeProvider'];

function config($routeProvider) {
   $routeProvider
      .when('/test1', {
         templateUrl: '/Home/Test1',
         isActive: 'test1'
      })
      .when('/test2', {
         templateUrl: '/Home/Test2',
         isActive: 'test2'
      })
      .otherwise({
         redirectTo: '/'
      });
}

输出网址如下所示:localhost/Home/Index#/test1

问题:

我是否需要在HomeController中定义Actions以及为什么?我认为我只需要ActionResult索引,因为我使用PartialView()...当我点击菜单Test1时,如何实现以下URL:localhost/test1

2 个答案:

答案 0 :(得分:3)

除了@Andiih在他的回答中所说的内容。 Angular路由库旨在处理您的Angular路由E.G. 之间(缺少一个更好的术语) 前端控制器。

您似乎已经将AngularASP.NET MVC路由混合在一起,就像您期望2工作一样。从那时起,您的基本路线为localhost/Home/Index# Angular将其自己的(子)路线附加到基座URL,从而产生您已查看的输出URL

尽管根据需要在MVCAngular路由和控制器之间跳转可能是可行的,但这比我假设你的目标更加复杂。实现。此外,我过去也从未需要这样做。

总结一下目前会发生什么:

如果您不得不离开Index.cshtml&#34; Root&#34;您实际导航离开当前的Angular应用..或者将导航到其他应用...根据解决方案结构,您甚至可以使用不同的JavaScript MV *框架对于每个单独的页面......但这只是疯狂。

Current App

...但我怀疑这是你在这个阶段想要的,所以为了简单起见,我们坚持假设你只有一个ASP.Net MVC Route / Page,而你只是想在{{1}之间导航路由并以某种方式从后端Angular服务向Angular路由或页面提供数据。

enter image description here

因此,您似乎可能错过了每个框架在您当前拥有的堆栈中扮演的角色之间的链接。 (我会尝试澄清)

例如:

如果你看一下(非常通用的)整体解决方案结构,可能如下所示。

.NET

- css - bootstrap.css // all 3rd party css here - libs - angular.js // all 3rd party js libs here - angular-ui-router.js - controllers - RootController.cs // This is your HomeController. // It's effectively used to "deliver" the root view which is // your core/base page for lack of a better term - views - RootView.cshtml // see code RootView.cshtml below, // this defines your app "layout" // as well as where you deliver your bundles, // make use of server side auth, etc.. - webapi - test1Api.cs // access to test1 data or serverside process - test2Api.cs // etc.. - app - pages - home - test1 - test1Ctrl.js - test1View.html - test1.css - test2 - test2Ctrl.js - test2View.html - test2.css - services - someRandomSvc.js - resourceSvc.js // this is where you consume your // .NET back end API. E.G: test1Api & test2Api, etc.. - app.js - app.routes.js - etc... 构建服务器端,因此允许您使用RootView.cshtml.NET bundling等。无论如何,整个页面将充当{{1}的shell } app,整个&#34;前端应用程序&#34;因此在该页面的上下文中运行。

<强> RootView.cshtml

Asp.NET Auth

您只需要一个Angular,正如我之前所述,您不会离开它(至少对于此应用)

<强> RootController.cs

<head>
    @Styles.Render("~/content/3rdPartyCSS")
    @Styles.Render("~/content/appSpecificCSS")
</head>
<body>
    <div class="navbar navbar-default navbar-fixed-top">
    <div class="container">
        <div class="navbar-collapse collapse glyphicons pull-right">
            <ul class="nav navbar-nav">
                <li><a ui-sref="home">Home</a></li>
                <li><a ui-sref="test1">Test1</a></li>
                <li><a ui-sref="test2">Test2</a></li>
            </ul>
        </div>
    </div>
    </div>
    <div class="container body-content">
        <div ng-view></div>
    </div>

    @Scripts.Render("~/bundles/3rdPartyJS")
    @Scripts.Render("~/bundles/appSpecificJS")
</body> 

...但您需要多条ASP.Net MVC Route路线。

<强> app.routes.js

namespace Tests.Controllers
{
    public class RootController : Controller
    {
        public ActionResult RootView()
        {
            // as I've mentioned previously in another post, 
            // we're returning a partial to avoid the usage of _layout.cshtml 
            // as our RootView is acting as the layout in for the angular app.          
            // (it would introduce another level of not needed nesting)
            return PartialView();
        }
    }
}

然后,您将通过WebAPI通过类似ngResource之类的内容通过min safe端点公开其他服务器端逻辑或调用,然后您将在Angular控制器中使用

<强> testXView.html

var app = angular.module('Tests');
app.config(['$stateprovider', function($stateprovider) {     
  $stateprovider
     .state('home', { url: '', templateUrl: 'app/pages/home/homeView.html' }])
     .state('test1', { url: '/test1', templateUrl: 'app/pages/test1/test1View.html'})
     .state('test2', { url: '/test2', templateUrl: 'app/pages/test2/test2View.html'});    
}]);

<强> testXCtrl.js

Angular

注意:

  1. 使用角度<div ng-controller="testXCtrl as test">{{ test.something }}</div> 的约定来制作代码angular-ui-router。 (所以当你看到它时不要太害怕)
  2. 我在我的示例中使用了一个名为{{3}}的路由库,我建议您查看它,如果您可以在此阶段自由选择...但相同的主体将适用于{ {1}}解决方案。

答案 1 :(得分:0)

在我看来,您试图让MVC将模板URL解析为部分。如果是这样,那么你就不能为MVC路线和Angular路线使用相同的路线。

将此分解为步骤

1)您是否需要MVC来解析模板路由(即具有动态生成的模板)如果您这样做,请创建模板控制器,并将每个模板构建为模板控制器上的部分操作。如果您不需要动态模板,只需将模板作为静态HTML存储在/ Content / Templates等文件夹中 - 这样可以避免使用MVC管道。

2)如果你得到1),你应该有一个有效的例子,但是有#个路线。要使HTML5路由正常工作,您需要从MVC管道中排除这些路由 - routes.IgnoreRoute(&#34; / Index / *&#34;);在RouteConfig.cs中可能有用 - 我没有尝试过。