在單頁面應用中要把各個分散的視圖給組織起來是經過路由機制來實現的。本文主要對 AngularJS 原生的 ngRoute
路由模塊和第三方路由模塊 ui.router
的用法進行簡單介紹,並作一個對比。html
1) 引入 angular-route
lib正則表達式
不管是 ngRoute
仍是 ui.router
,做爲框架額外的附加功能,都必須以 模塊依賴
的形式被引入。promise
1 |
<script src="lib/angular-route.js"></script> |
2) 配置路由瀏覽器
1 |
var app = angular.module('ngRouteApp', ['ngRoute']); |
ngRoute
路由模塊名app
$routeProvider
服務提供者,用來定義一個路由表,即地址欄與視圖模板的映射,對應於 ui.router
中的 urlRouterProvider
和 stateProvider
框架
$route
服務,完成路由匹配,而且提供路由相關的屬性訪問及事件,如訪問當前路由對應的 Controller,對應於下面的 $urlRouter
和 $state
$routeParams
服務,保存了地址欄中的參數,對應於下面的 $stateParams
dom
ng-view
指令,用來在主視圖中指定加載子視圖的區域,對應於下面的 ui-view
ide
1) 引入 angular-ui-router
lib函數
1 |
<script src="lib/angular-ui-router.min.js"></script> |
2) 配置路由工具
1 |
var app = angular.module("uiRouteApp", ["ui.router"]); |
ui.router
路由模塊名
$urlRouterProvider
服務提供者,用來配置路由重定向$stateProvider
服務提供者,用來配置路由
$urlRouter
服務$state
服務,用來顯示當前路由狀態信息,以及一些路由方法(如:跳轉)$stateParams
服務,用來存儲路由匹配時的參數
ui-view
指令,路由模板渲染,對應的 dom 相關聯ui-sref
指令,連接到特定狀態
調用 $stateProvider.state(...)
方法,並可配置如下參數
1 |
$stateProvider |
有兩種方式能夠指定父子狀態關係。
一種是,使用點標記法,像本文最後嵌套視圖部分舉得栗子那樣:
1 |
.state("tabs.tab1", {}) |
另外一種是,使用 parent
屬性
1 |
.state("tab1", { |
使用 abstract
能夠爲全部的子狀態提供一個基 URL
,這樣作的好處就是能夠在抽象出來的這個狀態所對應的 html
頁面中來定義靜態資源。抽象模板不能被激活。
1 |
$stateProvider |
resolve
在 state
配置參數中,是一個對象(key-value
),每個 value
都是一個能夠依賴注入的函數,而且返回的是一個 promise
(固然也能夠是值)。
1 |
resolve: { |
這樣作的目的:
controller
的操做,將數據的獲取放在 resolve
中進行,這在多個視圖多個 controller
須要相同數據時,有必定的做用。reslove
中的 promise
所有 resolved
(即數據獲取成功)後,纔會觸發 $stateChangeSuccess
切換路由,進而實例化 controller
,而後更新模板。更多參數可參考 angular 系列八 ui-router詳細介紹及ngRoute工具區別 中 state 參數的講解。
url
動態部分被稱爲參數,有如下幾種方式設置
1) 使用花括號的方式能夠設置一個正則表達式規則的參數:
1 |
//只會匹配 pageId 爲1到8位的數字 |
能夠經過 ?
來指定參數做爲查詢參數
1 |
//好比匹配 href="/page?type='new'" |
若是須要不止一個查詢參數,用 &
分隔:
1 |
//好比匹配 ui-sref="page({type:'all', title:'test ui-router'})" |
angular
在剛開始的 $digest
時,$rootScope
會觸發 $locationChangeSuccess
事件(angular
在每次瀏覽器 hash
change 的時候也會觸發 $locationChangeSuccess
事件)ui.router
監聽了 $locationChangeSuccess
事件,因而開始經過遍歷一系列 rules
,進行路由查找匹配列表項$state.transitionTo(state,...)
,跳轉激活對應的 state
在視圖中,建議使用 ui-sref="xxxState"
而不是 href="#/abc"
,這樣作能減小一遍 rules
循環的遍歷,提高性能。
ngRoute模塊
是 Angular 自帶的路由模塊,而 ui.router模塊
是基於 ngRoute模塊
開發的第三方模塊。
ui.router
是基於 state
(狀態)的, ngRoute
是基於 url
的,ui.router模塊
具備更強大的功能,主要體如今視圖的嵌套方面。
頁面某個動態變化區塊中,嵌套着另外一個能夠動態變化的區塊。
前面的栗子就是一個很好的業務場景。
在首頁中包含一個動態區塊:
1 |
<body ng-app="ngRouteApp"> |
在標籤頁中又包含動態區塊:
1 |
<div> |
一運行,報了一個這樣的錯誤:
RangeError: Maximum call stack size exceeded
發現瀏覽器崩潰了,由於 ng-view
會陷入死循環,無限遞歸下去。
使用 ui.router
能很容易解決這個問題,由於它定義的路由有明確的父子關係,並經過 ui-view
指令將子路由模版插入到父路由模板的 <div ui-view></div>
中去,從而實現視圖嵌套。看代碼:
1 |
$stateProvider |
ui-router(左) : ngRoute(右)