AngularJS路由主要有內置的ngRoute和一個基於ngRoute開發的第三方路由模塊ui-router,內置的ngRoute有時知足開發需求,使用ui-router能夠解決不少原生ngRoute的不足。
AngularJS的路由其實是一種純前端的解決方案,它的本質是:當請求一個url時,根據路由配置這個url,而後再請求模板片斷,並插入到ng-view中。AngularJS的路由更傾向於經過改變url進行頁面的局部刷新。javascript
使用ngRoute須要額外加載這個模塊文件,如:html
<script src="../angular/angular.js"></script> <script src="../angular-route/angular-route.js"></script>
同時還須要在模塊聲明中注入對ngRoute的依賴:前端
var app = angular.module('MyApp', ['ngRoute']);
使用ngRoute包含如下幾個內容:java
名稱 | 所屬 | 使用 |
---|---|---|
ngView | directive | 提供不一樣路由模板插入的視圖層 |
$routeProvider | provider | 提供路由配置 |
$route | service | 用於構建各個路由的url,view,controller的關係 |
$routeParams | service | 解析返回路由中帶有的參數 |
$routeProvider提供了定義路由表的服務,有兩個核心方法:
1. when(path,route)
path: string類型,表示該條路由規則所匹配的路徑。
注意: 若是路徑中須要匹配參數,如path路徑是:/show/:name,若是地址欄爲:/show/lydia,那麼這裏的name以及所對應的值lydia都會保存在$routeParams服務中,須要經過$routeParams.name來獲取。
route: object類型,用來指定一系列配置項。npm
配置 | 說明 |
---|---|
controller | 控制器名稱 |
controllerAs | 給控制器起個別名 |
template | 對應路徑的頁面模板,會出如今ng-view處 |
templateUrl | 對應模板的路徑 |
resolve | 該屬性會以鍵值對對象的形式,給路由相關的控制器綁定服務或者值。而後把執行的結果值或者對應的服務引用,注入到控制器中。若是resolve中是一個promise對象,那麼會等它執行成功後,才注入到控制器中,此時控制器會等待resolve中的執行結果。 |
redirectTo | 重定向地址 |
reloadOnSearch | 設置是否在只有地址改變時,才加載對應的模板。search和params改變都不會加載模板。默認爲true,當$location.search()發生變化時會從新加載路由。 |
caseInsensitiveMatch | 路徑區分大小寫 |
2.otherwise(params)
對應了路徑匹配不到時的狀況。promise
第一步:添加頁面
html頁面,哪裏須要局部刷新,哪裏就用ng-view:app
<body ng-app="routeApp"> <div ng-view></div> <script src="bower_components/angular/angular.js"></script> <script src="scripts/app.js"></script> <script src="scripts/controllers/main.js"></script> </body>
第二步:controller添加路由配置ide
var routeApp = angular.module('routeApp',[]); routeApp.config(['$routeProvider',function ($routeProvider) { $routeProvider .when('/list', { templateUrl: 'views/route/list.html', controller: 'RouteListCtl' }) .when('/list/:id', { templateUrl: 'views/route/detail.html', controller: 'RouteDetailCtl' }) .otherwise({ redirectTo: '/list' }); }]);
再添加兩個controller函數
routeApp.controller('RouteListCtl',function($scope) { }); routeApp.controller('RouteDetailCtl',function($scope, $routeParams) { $scope.id = $routeParams.id; });
上面這個例子只是簡單的例舉一下帶參數和不帶參數的url的路由配置和獲取方法,具體的html頁面和結果就不展現了。ui
$routeProvider的第二個參數是路由的一些具體配置項目,這裏有一個比較重要的配置,即resolve。配置resolve意味着在進入這個路由以前必須等待resolve中的數據返回,也就是說,在跳轉目標路由以前先作一些額外工做去預加載數據,只有當數據準備穩當以後,纔會去載入目標路由的模板和執行相應的controller。
$routeProvider .when("/news", { templateUrl: "newsView.html", controller: "newsController", resolve: { message: function(messageService){ return messageService.getMessage(); } } })
在上例中,只有message有值的狀況下才會去加載html頁面和js。
在路由跳轉以前,會觸發resolve下的全部promise,只有當全部的promise都被正確的resolve以後纔會進行路由切換,此時$route會拋出$routeChangeSuccess的事件,若是沒有被正確的resolve,那麼$route會拋出$routeChangeError的事件,而且終止路由切換。
ui-router相比ngRoute的優點在於,一個頁面能夠嵌套多個視圖,,建立嵌套分層的視圖,多個視圖去控制某一個視圖等。
安裝:
npm install angular-ui-router --save
同時在項目中引入:
<script type="text/javascript" src="app/bower_components/angular-ui-router/release/angular-ui-router.js"></script>
對應的controller中引入ui-router的依賴:
angular.module('myApp', ['ui.router']);
ui-router包含的內容與ngRoute很像,能夠進行一下類比:
ngRoute | ui-router |
---|---|
ng-view | ui-view |
$routeProvider | $stateProvider |
$routeParams | $stateParams |
$route | $state |
1.$state配置參數
參數 | 說明 |
---|---|
url | 默認相對路徑(以^開頭的是絕對路徑) |
views | views裏的每一個子視圖能夠包含本身的模板、控制器和預載入數據 |
abstract | 抽象模板不能被激活 |
template | HTML字符串或者返回HTML字符串的函數 |
舉個例子:
html頁面:
<body> <div> <div ui-view="filters"></div> <div ui-view="mailbox"></div> <div ui-view="priority"></div> </div> </body>
js:
angular.module('myApp').config(['$stateProvider',function($stateProvider) { $stateProvider .state('report',{ views: { 'filters': { template: '<h4>Filter inbox</h4>', controller: function($scope) {} }, 'mailbox': { templateUrl: 'partials/mailbox.html' }, 'priority': { template: '<h4>Priority inbox</h4>', resolve: { facebook: function() { return FB.messages(); } } } } }).state('blog',{ url:'/blog', views:{ 'container':{templateUrl:'templates/blog/layout.html'} } })
abstract抽象模板
抽象模板不能被激活,可是它的子模板能夠被激活。抽象模板一般用於提供一個包括了不少視圖的模板,它能夠傳遞$scope做用域給子模板,也能夠在同一個url下傳遞自定義數據或預加載的依賴。如:
$stateProvider .state('admin', { abstract: true, url: '/admin', template: '<div ui-view></div>' }) .state('admin.index', { url: '/index', template: '<h3>Admin index</h3>' }) .state('admin.users', { url: '/users', template: '<ul>...</ul>' });
2.$stateParams
使用$stateparams來提取在url中的不一樣參數。
若是一個url是這樣的:
'/inbox/:inboxId/messages/{sorted}?from&to'
當用戶訪問時,請求的url是這樣的:
'/inbox/123/messages/ascending?from=10&to=20'
那麼$stateParams對象的值爲:
{inboxId: '123', sorted: 'ascending', from: 10, to: 20}
3.$urlRouterProvider
$urlRouterProvider和ngRoute同樣,有when()和otherwise()兩種用法,除此以外,還有rule()方法,能夠越過任何url的匹配或者在其餘路由前作路由修改,函數返回一個有效的路徑的字符串。
app.config(function($urlRouterProvider){ // 忽略url的大小寫 $urlRouterProvider.rule(function ($injector, $location) { var path = $location.path(), normalized = path.toLowerCase(); if (path != normalized) return normalized; }); })
路由的匹配方式
url:"/user/:id"
url:"/user/{id}"
上面的這兩個寫法是同樣的。
// 只會匹配 contactId 爲1到8位的數字 url: "/contacts/{contactId:[0-9]{1,8}}"
能夠經過?來指定參數做爲查詢參數,如:
url: "/contacts?myParam" //匹配 "/contacts?myParam=value" url: "/contacts?myParam1&myParam2" // 匹配 "/contacts?myParam1=value1&myParam2=wowcool"