为什么需要前端路由
Ajax请求不会留下history记录 
- 用户无法直接通过 url 进入应用中的指定页面(保存书签,链接分享给朋友)
 
Ajax对SEO不友好(没法让搜索引擎索引) 
Angular 路由
在APP中定义多个页面的控制器,并给出对应的模板。然后$routeProvider进行配置,即可将 URL 映射到这些控制器和视图。 首先定义一个基本的 Angular APP,并引入ngRoute:
Angular$routeService在ngRoute模块里。需要引入它对应的 JavaScript 文件,并在我们的 APP 里ngRoute添加为模块依赖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | var app = angular   .module('ngRouteExample', ['ngRoute'])   .controller('MainController', function($scope) {})   .config(function($routeProvider, $locationProvider) {     $routeProvider       .when('/users', {         templateUrl: 'user-list.html',         controller: 'UserListCtrl'       })       .when('/users/:username', {         templateUrl: 'user.html',         controller: 'UserCtrl'       })       .otherwise({         redirectTo: '/hello'       })
           $locationProvider.html5Mode(true)   })
   | 
 
上述代码中,$routeProvider定义了两个 URL 的映射:/users使用user-list.html作为模板,UserListCtrl作为控制器;/users/:username则会匹配类似/users/alice之类的 URL,稍后你会看到如何获得:username匹配到的值。先看首页的模板:
HTML5Mode: 服务器端路由和客户端路由的 URL 以#分隔。例如/foo/bar#/users/alice,Angular 通过操作锚点来进行路由。 然而html5Mode(true)将会去除#,URL 变成/foo/bar/users/alice(这需要浏览器支持 HTML5 的,因为此时 Angular 通过pushState来进行路由)。 此时服务器对所有的客户端路由的 URL 都需要返回首页(/foo/bar)视图,再交给 Angular 路由到/foo/bar/users/alice对应的视图。
1 2 3 4 5
   | <div ng-controller="MainController">   Choose: <a href="users">user list</a> | <a href="users/alice">user: alice</a>
    <div ng-view></div> </div>
   | 
 
注意到模板文件中有一个div[ng-view],子页面将会载入到这里。
路由参数
用户列表页面:
1
   | app.controller('UserListCtrl', function($scope) {})
  | 
 
1 2
   |  <h1>User List Page</h1>
 
  | 
 
用户页面:
1 2 3
   | app.controller('UserCtrl', function($scope, $routeParams) {   $scope.params = $routeParams })
  | 
 
1 2 3
   |  <h1>User Page</h1> <span ng-bind="params.userName"></span>
 
  | 
 
我们点击首页的/users/alice时,将会载入user.html,span的值为alice。$routeParams提供了当前的路由参数,例如:
1 2 3 4 5 6
   | 
 
 
 
  $routeParams ==> {chapterId:'1', sectionId:'2', search:'moby'}
 
  | 
 
UI-Router
UI-Router 是 Angular-UI 提供的客户端路由框架,它解决了原生的 ng-route 的很多不足:
- 视图不能嵌套。这意味着
$scope会发生不必要的重新载入。这也是我们在Onboard 中引入 ui-route 的原因。 
- 同一 URL 下不支持多个视图。这一需求也是常见的:我们希望导航栏用一个视图(和相应的控制器)、内容部分用另一个视图(和相应的控制器)。
 
UI-Router 提出了$state的概念。一个$state是一个当前导航和 UI 的状态,每个$state需要绑定一个 URL Pattern。 在控制器和模板中,通过改变$state来进行 URL 的跳转和路由。这是一个简单的例子:
1 2 3 4
   |  <body ng-controller="MainCtrl">   <section ui-view></section> </body>
 
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   |  var myUIRoute = angular.module('MyUIRoute', ['ui.router', 'ngAnimate']) myUIRoute.config(function($stateProvider, $urlRouterProvider) {   $urlRouterProvider.otherwise('/contacts')   $stateProvider     .state('contacts', {       url: '/contacts',       template: 'contacts.html',       controller: 'ContactCtrl'     })     .state('contacts.detail', {       url: '/contacts/:contactId',       templateUrl: 'contacts.detail.html',       controller: function($stateParams) {                  $stateParams.contactId === '42'       }     }) })
 
  | 
 
当访问/contacts时,contacts $state被激活,载入对应的控制器和视图。在 ui-router 时,通常使用$state来完成页面跳转, 而不是直接操作 URL。例如,在脚本使用$state.go:
1 2
   | $state.go('contacts')  $state.go('contacts.detail', { contactId: 42 }) 
  | 
 
在模板中使用ui-sref(这是一个 Directive):
1 2
   | <a ui-sref="contacts">Contacts</a> <a ui-sref="contacts.detail({contactId: 42})">Contact 42</a>
   | 
 
嵌套视图
不同于 Angular 原生的ng-route,ui-router 的视图可以嵌套,视图嵌套通常对应着$state的嵌套。 contacts.detail是contacts的子$state,contacts.detail.html也将作为contacts.html的子页面:
1 2 3
   |  <h1>My Contacts</h1> <div ui-view></div>
 
  | 
 
1 2
   |  <span ng-bind="contactId"></span>
 
  | 
 
上述ui-view的用法和ng-view看起来很相似,但不同的是ui-view可以配合$state进行任意层级的嵌套, 即contacts.detail.html中仍然可以包含一个ui-view,它的$state可能是contacts.detail.hobbies。
命名视图
在 ui-router 中,一个$state下可以有多个视图,它们有各自的模板和控制器。这一点也是ng-route所没有的, 给了前端路由极大的灵活性。来看例子:
1 2 3 4 5 6
   |  <body>   <div ui-view="filters"></div>   <div ui-view="tabledata"></div>   <div ui-view="graph"></div> </body>
 
  | 
 
这一个模板包含了三个命名的ui-view,可以给它们分别设置模板和控制器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | $stateProvider   .state('report',{     views: {       'filters': {         templateUrl: 'report-filters.html',         controller: function($scope){ ... controller stuff just for filters view ... }       },       'tabledata': {         templateUrl: 'report-table.html',         controller: function($scope){ ... controller stuff just for tabledata view ... }       },       'graph': {         templateUrl: 'report-graph.html',         controller: function($scope){ ... controller stuff just for graph view ... }       }     }   })
   | 
 
综合实例
HTML:
1 2
   | //uiRoute.html <div ui-view></div>
   | 
 
1 2 3 4 5 6 7
   | //index.html <div class="container">   //头部   <div ui-view="topbar"></div>   //主体   <div ui-view="main"></div> </div>
   | 
 
1 2 3 4 5 6 7 8 9 10
   | //topbar.html //顶部 <nav class="navbar navbar-inverse" role="navigation">   <div class="navbar-header">     <a class="navbar-brand" ui-sref="#">ui-router综合实例</a>   </div>   <ul class="nav navbar-nav">     <li><a ui-sref="index">首页</a></li>     <li><a ui-sref="index.usermng">用户管理</a></li>   </ul> </nav>
   | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
   | //usermng.html //左侧 <div class="row">   <div class="col-md-3">     <div class="row">       <div class="col-md-12">         <div class="list-group">           <a ui-sref="#" class="list-group-item active">用户分类</a>           <a ui-sref="index.usermng.highendusers" class="list-group-item"             >高端用户</a           >         </div>       </div>     </div>     <div class="row">       <div class="col-md-12">         <button class="btn btn-primary" ng-click="addUserType()">           新增用户         </button>       </div>     </div>   </div>   <div class="col-md-9">     //用于存放右边部分     <div ui-view></div>   </div> </div>
   | 
 
javascript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
   | var routerApp = angular.module('routerApp', ['ui.router']) routerApp.config(function($stateProvider, $urlRouterProvider) {   $urlRouterProvider.otherwise('/index')   $stateProvider     .state('index', {       url: '/index',       views: {         '': {           templateUrl: 'tpls/index.html'         },         'topbar@index': {           templateUrl: 'tpls/topbar.html'         },         'main@index': {           templateUrl: 'tpls/home.html'         }       }     })     .state('index.usermng', {       url: '/usermng',       views: {         'main@index': {           templateUrl: 'tpls/usermng.html',           controller: function($scope, $state) {             $scope.addUserType = function() {               $state.go('index.usermng.addusertype')             }           }         }       }     })     .state('index.usermng.highendusers', {       url: '/highendusers',       templateUrl: 'tpls/highendusers.html'     })     .state('index.usermng.addusertype', {       url: '/addusertype',       templateUrl: 'tpls3/addusertypeform.html',       controller: function($scope, $state) {         $scope.backToPrevious = function() {           window.history.back()         }       }     }) })
  | 
 
转载自:http://harttle.com/2015/06/10/angular-route.html