如何在ASP.NET MVC中定义角路由 [英] How to define Angular Routing in ASP.NET MVC

查看:71
本文介绍了如何在ASP.NET MVC中定义角路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于在Asp.Net MVC应用程序中使用Angular的路由,我有些困惑.

I'm a bit confused about using the routing of Angular within an Asp.Net MVC app.

要理解我的问题,我将显示应用程序的当前代码:

To understand my question I will shown the currently code of my app:

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: '/'
      });
}

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

The output URL is shown as follows: localhost/Home/Index#/test1

问题:

我需要在HomeController中定义动作吗,为什么?我以为我只需要ActionResult索引,因为我使用PartialView()...,如何单击菜单Test1来获得以下URL:localhost/test1?

Do I need to define Actions in HomeController and why? I thought I need just the ActionResult Index because I use PartialView()... And how can I achieve the following URL: localhost/test1 when I click on the Menu Test1?

推荐答案

除了@Andiih在他的回答中指出的内容. Angular路由库旨在处理您的Angular路由E.G. (缺乏更好的称呼) 前端控制器之间.

In addition to what @Andiih stated in his answer. The Angular routing library is meant to handle your Angular routes E.G. between (for lack of a better term) front end controllers.

您似乎以期望2起作用的方式混合了AngularASP.NET MVC布线.从此以后,您的基本路由为localhost/Home/Index# Angular会将其自身的(子)路由附加到基本URL,从而得到您所看到的输出URL.

You seem to have mixed Angular and ASP.NET MVC routing in the way you're expecting the 2 to work. Your base route is localhost/Home/Index# from that point onward Angular appends its own (sub) routes to the base URL, resulting in the output URL that you're seeing.

即使根据需要在MVCAngular路径与控制器之间进行跳转可能是可行的,但与我假设要实现的目标相比,这将是一个更为复杂的场景.另外,我从不需要到那种程度.

Even though it might be feasible jumping between MVC and Angular routes and controllers as needed, it would be a more complicated scenario than what I'm assuming you're aiming to achieve. Also I've never needed to go to that extent in the past.

总结当前将发生的情况:

如果您必须离开Index.cshtml根"页面,则实际上是离开当前的Angular应用..或导航其他应用...根据解决方案的结构,您甚至可以为每个单独的页面使用不同的JavaScript MV *框架...但这只是疯狂.

If you had to navigate away from your Index.cshtml "Root" page you'd in effect navigate away from your current Angular app.. or navigate to a different app... depending on solution structure you could even use different JavaScript MV* framework for each a separate page... but that's just madness.

...但是我怀疑这是您当前想要的,因此为简单起见,我们假设您只有一个ASP.Net MVC Route/Page,而您只是想在Angular路线之间导航,以某种方式从后端.NET服务向Angular路由或页面提供数据.

...but I doubt it is what you want at this stage, so for simplicity sake lets stick to assuming you only have the one ASP.Net MVC Route / Page, and you just purely want to navigate between Angular routes and supply data to the Angular routes or pages from your back end .NET services somehow.

因此,您似乎可能会缺少每个框架在当前堆栈中要扮演的角色之间的联系. (我会尽力澄清)

Thus it seems that you could potentially be missing a link between what roles each of the frameworks are meant to play in the stack you currently have. (I'll try clarify)

例如:

如果您查看的是(非常通用的)整体解决方案结构,则可能类似于以下内容.

If you look at a (very generic) overall solution structure that could look something like this below.

    - 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 bundlingAsp.NET Auth等.无论如何,整个页面将充当Angular应用程序的外壳,即整个前端".应用",因此可以在该页面的上下文中运行.

The RootView.cshtml gets constructed server-side, thus allowing you to use .NET bundling, Asp.NET Auth etc.. Anyhow, this whole page will act as a shell for the Angular app, the whole "front end app", thus runs within the context of that page.

RootView.cshtml

<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,就像我之前说过的那样,您就不会离开它(至少对于这个应用程序而言)

You'll only need a single ASP.Net MVC Route, as I've stated before, you won't be navigating away from it (for this app at-least)

RootController.cs

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

...但是您将需要多个Angular路线.

... but you will need multiple Angular routes.

app.routes.js

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

然后,您将通过

You would then expose the other server-side logic or calls via WebAPI endpoints that you would need to consume via something like ngResource, which you will then utilize in your Angular controllers.

testXView.html

<div ng-controller="testXCtrl as test">{{ test.something }}</div>

testXCtrl.js

var app = angular.module('Test');
app.controller('testXCtrl',['resourceSvc', function(resourceSvc) {
   resourceSvc.getSomeData().then(function(data) {
       this.something = data;  //.. or whatever floats your boat :P
   })
}]);

注意.

  1. 将此惯例与angular .something(['service', function(service) { }]);结合使用,是为了使代码最小安全. (所以当您看到它时不要太害怕)
  2. 在我的示例中,我使用了名为 angular-ui-router 的路由库,我建议您看看一下,如果您可以在此阶段自由选择的话...但是相同的原理适用于ngRoute解决方案.
  1. Using this convention with angular .something(['service', function(service) { }]); is to make the code min safe. (So don't be too scared when you see it)
  2. I used a routing library called angular-ui-router in my example, I suggest that you have a look at it, if you have the freedom to choose at this stage... but the same principals would apply to an ngRoute solution.

这篇关于如何在ASP.NET MVC中定义角路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆