1.背景介紹
UI-Router它是一個讓開發者能夠根據URL狀態或者說是'機器狀態'來組織和控制界面UI的渲染,而不是僅僅只改變路由(傳統AngularJS應用實用的方式)。該模塊為開發者提供了很多視圖(view)額外的控制。開發者可以創建嵌套分層的視圖、在同一個頁面使用多個視圖、讓多個視圖控制某個視圖等更多的功能。
2.知識剖析
$stateProvider:管理狀態定義、當前狀態和狀態轉換。包含觸發狀態轉換的事件和回調函數,異步解決目標狀態的任何依賴項,更新$location到當前狀態。由于狀態包含關聯的url,通過$urlRouterProvider生成一個路由規則來執行轉換的狀態。
ui-view指示器:渲染狀態中定義的視圖,是狀態中定義的視圖的一個占位符。
$urlRouter /$urlRouterProvider:管理了一套路由規則列表來處理當$location發生變化時如何跳轉。最低級的方式是,規則可以是任意函數,來檢查$location,并在處理完成時候返回true。支持正則表達式規則和通過$urlMatcherFactory編譯的UrlMatcher對象的url占位符規則。
$urlMatcherFactory:將url和占位符編譯為UrlMatcher對象。除了$routeProvider支持的占位符語法之外,它還支持擴展語法,允許一個正則表達式指定占位符,并且能夠提取命名參數和查詢url的一部分。
首先引入源文件,接下來將UI-Router作為web應用的依賴,注入到主程序:
angular.module('myApp',['ui.router'])
與集成的ngRoute服務不同的是,UI-Router可以將視圖嵌套,因為它基于的是操作狀態而僅非URL。與傳統做法使用ng-view不同的是,在ngRoute里需要使用ui-view服務。當在ui-router中處理路由和狀態時,開發者的重心是當前的狀態是什么以及在哪一個頁面里。
和ngRoute一樣,為特定狀態指定的模板將會放在ui-view元素中。在這些模板中也可以包含自己的ui-view,這就是在同一個路由下實現嵌套視圖的方法。要定義一個路由,與傳統的方法相同:使用.config方式,但使用的不是$routeProvider而是$stateProvider。
模板,模板路徑,模板Provider
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('start', {
url: '/start',
templateUrl: 'Hello {{ name }}';
})
上述代碼在設置對象上定義了一個叫start的狀態。設置對象stateConfig和路由設置對象的選項是非常相似的。開發者可以在每個視圖下使用如下方式來設置模板template -HTML字符串,或者是返回HTML字符串的函數templateUrl - HTML模板的路徑,或者是返回HTML模板路徑的函數templateProvider,返回HTML字符串的函數。
url選項將會為該應用的狀態指定一個URL基于用戶瀏覽該應用所在的狀態。這樣當在瀏覽該應用的時候便能實現深度鏈接的效果。
$stateProvider
.state('inbox', {
url: '/inbox/:inboxId',
template: 'Welcome to修真院',
controller: function($scope, $stateParams) {
$scope.inboxId = $stateParams.inboxId;
}
});
當用戶瀏覽到/index時,該應用將狀態改為index同時向主ui-view元素中插入template中的內容。
inboxId為URL的第二個部分,例如:訪問/inbox/1,那么$stateParams.inboxId就為1($stateParams為{inboxId:1})。同時也可使用不同的語法:url: '/inbox/{inboxId}'
嵌套路由
使用url參數可以實現嵌套的路由,有了嵌套路由便可在同一個模板同一個路由實現多層次的ui-view,例如在/inbox中嵌入更多路由:
$stateProvider
.state('inbox', {
url: '/inbox/:inboxId',
template: 'Welcome to修真院
\
Show priority\
\
',
controller: function($scope, $stateParams) {
$scope.inboxId = $stateParams.inboxId;
}
})
.state('inbox.priority', {
url: '/priority',
template: 'Your priority inbox'
});
.state('inbox.priority'是/inbox下的一個子路由:state( . )語法指定了它使子路由。/inbox/1將匹配第一個路由,而/inbox/1/priority會匹配第二個路由。使用這種語法,在父視圖中的ui-view元素將會由第二個路由控制。
Views視圖
開發者可以在同一個模板中改變和切換不同的視圖。如果設置了視圖選項,則該狀態的‘template’,‘templateUrl’及‘templateProvider’將被忽略。如果想在路由里包含父級模板,就需要創建一個包含模板的抽象模板。例如:
ui-view="filters"
ui-view="mailbox"
ui-view="priority"
接下來創建分別被插入到上述ui-view的有命名的視圖,每個子視圖可以包含自己的模板、控制器和預載入數據。
$stateProvider
.state('inbox', {
views: {
'filters': {
template: 'Filter inbox',
controller: function($scope) {}
},
'mailbox': {
templateUrl: 'Mail inbox'
},
'priority': {
template: 'Priority inbox',
}
}
});
$stateParams狀態參數
該服務的作用是處理url的不同部分。例如,當上述的inbox狀態是這樣時:
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}
$urlRouterProvider
開發者可以在該對象上設定特定的URL被激活時做什么的規則。由于設定好的狀態在特定的url被訪問是會自動激活,所以$urlRouterProvider沒有必要用來管理激活和載入狀態。但當需要管理哪些被發生在當前狀態之外的作用域scope時它會非常有用,例如在重定向或者安全驗證的時候。在模塊的設置函數里便可使$urlRouterProvider。
when()
該函數需要兩個參數:1.當前的路徑,2.需要重定向到的路徑(或者是需要在路徑被訪問是運行的函數)。設置重定向前需要為$urlRouterProvider設置when函數來接受一個字符串。例如,當希望重定向一個空的路由到/inbox:
.config(function($urlRouterProvider) {
$urlRouterProvider.when('', '/inbox');
});
otherwise()
和ngRoute的otherwise()函數相似,在用戶提交的路徑沒有被定義的時候它將重定向到指定的頁面。這是個創建’默認‘路徑的好方法。otherwise()只接受一個參數,要么函數要么字符串,字符串必須為合法的url路由地址,函數則會在沒有任何路徑被匹配的時候被運行。
.config(function($urlRouterProvider) {
$urlRouterProvider.otherwise('/');
// or
$urlRouterProvider.otherwise(
function($injector, $location) {
$location.path('/');
});
});
rule()
如果想越過任何URL的匹配或者在其他路由前做路由修改,則可以使用rule()函數。在使用它的時候必須返回一個合法的代表路徑的字符串。
app.config(function($urlRouterProvider){
$urlRouterProvider.rule(
function($injector, $location) {
return '/index';
});
})
參考文獻
深入理解ANGULARUI路由_UI-ROUTER:
www.cnblogs.com/hughtxp/p/3965916.html
PPT: ? ?http://chowhengguang.oschina.io/demo/PPT10.html#/