AngularJS路由之ui-router(一)
在angular1有內建的路由服務,使用$route可以幫助實現路由的切換,檢視的改變,但是$route只是包含了基本的功能,在很多場合不夠用。
uiRouter是第三方js庫。需要引入“angular-ui-router.min.js”檔案。
在Asp.Net中引入uiRouter簡單方法是使用Nuget:
服務與指令:
ui.router 路由模組名
$urlRouterProvider 服務提供者,用來配置路由重定向
$stateProvider 服務提供者,用來配置路由
$urlRouter 服務
$state 服務,用來顯示當前路由狀態資訊,以及一些路由方法(如:跳轉)
$stateParams 服務,用來儲存路由匹配時的引數
ui-view 指令,路由模板渲染,對應的 dom 相關聯
ui-sref 指令,連結到特定狀態
路由的建立:
基本配置
呼叫 $stateProvider.state(...) 方法,並可配置以下引數
$stateProvider
.state("Main", {
url: "/main",
templateUrl: 'main.html',
controller: 'MainCtrl',
})
parent-指定父子關係有兩種方式可以指定父子狀態關係。
一種是,使用點標記法,像本文最後巢狀檢視部分舉得栗子那樣:
.state("tabs.tab1", {})
另一種是,使用 parent 屬性
.state("tab1", {
parent: 'tabs' // 也可是一個狀態物件, parent: tabs
})
abstract
使用 abstract 可以為所有的子狀態提供一個基 URL,這樣做的好處就是可以在抽象出來的這個狀態所對應的 html 頁面中來定義靜態資源。抽象模板不能被啟用。
resolve$stateProvider .state('contacts', { abstract: true, url: '/contacts', templateUrl: 'contacts.html', }) .state('contacts.list', { url: '/list', templateUrl: 'contacts.list.html' })
resolve 在 state 配置引數中,是一個物件(key-value),每一個 value 都是一個可以依賴注入的函式,並且返回的是一個 promise (當然也可以是值)。
resolve: {
'myResolve': ['contacts',
function(contacts){
return contacts.all();
}]
}
這樣做的目的:簡化了 controller 的操作,將資料的獲取放在 resolve 中進行,這在多個檢視多個controller 需要相同資料時,有一定的作用。
只有當 reslove 中的 promise 全部 resolved(即資料獲取成功)後,才會觸發$stateChangeSuccess 切換路由,進而例項化 controller,然後更新模板。
路由控制
url 動態部分被稱為引數,有以下幾種方式設定
1) 使用花括號的方式可以設定一個正則表示式規則的引數:
//只會匹配 pageId 為1到8位的數字
url: "/pages/{pageId:[0-9]{1,8}}"
可以通過 ? 來指定引數作為查詢引數
//比如匹配 href="/page?type='new'"
url: "/page?type"
如果需要不止一個查詢引數,用 & 分隔:
//比如匹配 ui-sref="page({type:'all', title:'test ui-router'})"
url: "/page?type&title"
路由的查詢匹配
angular 在剛開始的 $digest 時,$rootScope 會觸發 $locationChangeSuccess 事件(angular 在每次瀏覽器 hash change 的時候也會觸發 $locationChangeSuccess 事件)
ui.router 監聽了 $locationChangeSuccess 事件,於是開始通過遍歷一系列 rules,進行路由查詢匹配列表項
當匹配到路由後,就通過 $state.transitionTo(state,...),跳轉啟用對應的 state
最後,完成資料請求和模板的渲染
在檢視中,建議使用 ui-sref="xxxState" 而不是 href="#/abc",這樣做能減少一遍 rules迴圈的遍歷,提升效能。
例項一、巢狀路由使用例項
1.新增引用:
<script src="../Scripts/angular.min.js"></script>
<script src="../Scripts/angular-ui-router.min.js"></script>
<link href="../Content/bootstrap.min.css" rel="stylesheet" />
2.app.js
var myApp = angular.module('myApp', ['ui.router']);
myApp.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider
.when("", "/PageTab")
.when("/", "/PageTab");
$stateProvider.state("PageTab", {
url: '/PageTab',
templateUrl: '/template/PageTab.html'
}).state('PageTab.Page1', {
url: '/Page1',
templateUrl: '../template/page1.html'
}).state('PageTab.Page2', {
url: '/Page2',
templateUrl: '../template/page2.html'
}).state('PageTab.Page3', {
url: '/Page3',
templateUrl: '../template/page3.html'
});
});
3.PageTab.thml
<div>
<span style="width:100px" ui-sref=".Page1"><a href="">Page-1</a></span>
<span style="width:100px" ui-sref=".Page2"><a href="">Page-2</a></span>
<span style="width:100px" ui-sref=".Page3"><a href="">Page-3</a></span>
</div>
<div>
<div ui-view="" />
</div>
4.Page1-3.html的內容
<h1 class="text-success">
Page1 頁面
</h1>
顯示結果:
更多: