ui-router和同屬性的AngularJS框架一部分的ng-route一樣強(qiáng)大偿警。ui-router提供了讓我們可以做路由嵌套和視圖命名的特征涩澡。
實(shí)戰(zhàn)
一般針對(duì)需求,我們可以使用AngularJS框架來(lái)創(chuàng)建簡(jiǎn)單的html和JavaScript頁(yè)面。下面我們將創(chuàng)建3個(gè)HTML頁(yè)面和一個(gè)JavaScript腳本文件
?? 一開始我們創(chuàng)建一個(gè)空的web應(yīng)用程序昌执,并加入三個(gè)HTML頁(yè)面。如下所示诈泼,這些頁(yè)面都是片段視圖懂拾。它們會(huì)在導(dǎo)航過(guò)程中展示。我們還要為能展示應(yīng)用程序的Tab铐达,創(chuàng)建另外一個(gè)叫做PageTab.html的頁(yè)面
??因此我們先創(chuàng)建以下文件:
1岖赋,Page1.html
2,Page2.html
3瓮孙,Page3.html
4唐断,PageTab.html
Page1.html
創(chuàng)建如下的html頁(yè)面:
<div>
??<div>
????<h>我踏遍輪回选脊,只為與你相遇</h1>
??</div>
</div>
Page2.html
創(chuàng)建如下的html頁(yè)面:
<div>
??<div>
????<h>我要這天再也遮不住我的眼</h1>
??</div>
</div>
Page3.html
創(chuàng)建如下的html頁(yè)面:
<div>
??<div>
????<h>要這地再也埋不住我的身</h1>
??</div>
</div>
PageTab.html
創(chuàng)建如下的html頁(yè)面:
<div>
??<div>
????<span style="width:100px"><a href="">Page-1</a></span>
????<span style="width:100px"><a href="">Page-2</a></span>
????<span style="width:100px"><a href="">Page-3</a></span>
??</div>
</div>
這將會(huì)使頁(yè)面文本處在側(cè)邊,并添加當(dāng)用戶鼠標(biāo)懸停在文本上的時(shí)候的超鏈接脸甘。
??我們沒(méi)有指向任何超鏈接恳啥,只是為了把鏈接放在href中,實(shí)際上這是一種獲取url的解決方式
??到目前為止丹诀,我們還沒(méi)有插入任何AngularJS路由或者其它任何框架角寸。目前我們只是創(chuàng)建了一些頁(yè)面片段,我們需要一個(gè)占位或者說(shuō)父頁(yè)面來(lái)裝下這些東西忿墅,我們可以將這個(gè)頁(yè)面起名為Main.html
Main.html
用如下內(nèi)容創(chuàng)建這個(gè)html頁(yè)面
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
??<title></title>
??<script src="Scripts/angular.js"></script>
??<script src="Scripts/angular-ui-router.js"></script>
??<script src="App.js"></script>
</head>
<body data-ng-app="myApp">
??<h>AngularJS Home Page (Ui-router Demostration)</h1>
??<div data-ui-view=""></div>
</body>
<html>
我們需要在主頁(yè)上做一些事情扁藕,(1)我們需要引入AngularJS框架(2)需要引入ui-router框架(3)引入AngularJS文件App.js(4)讓主頁(yè)內(nèi)容展示出來(lái),然后顯示出它里面的頁(yè)面
??而App.js文件的內(nèi)容疚脐,我們聲明了AngularJS模塊和路由配置亿柑。當(dāng)頁(yè)面加載的時(shí)候我們會(huì)在Main.html中顯示PageTab.html的內(nèi)容。代碼如下
App.js
var myApp=angular.module("myApp",['ui.router']);
myApp.config(function($stateProvider,$urlRouterProvider){
??$urlRouterProvider.when("","/PageTab");
??$stateProvide
.state("PageTab",{
??????url:"/PageTab",
??????templateUrl:"PageTab.html"
????})
????.state("PageTab.Page1",{
??????url:"/Page1",
??????templateUrl:"Page-1.html"
????})
????.state("PageTab.Page2",{
??????url:"/Page2",
??????templateUrl:"Page-2.html"
????})
????.state("PageTab.Page3",{
??????url:"/Page3",
??????templateUrl:"Page-3.html"
????});
});
現(xiàn)在來(lái)解釋這些步驟都是干啥的
代碼行
1棍弄,第一行望薄,聲明AngularJS模塊,并把ui-router傳入AngularJS主模塊呼畸,所有的結(jié)合起來(lái)我們就得到了Angular模塊
var myApp=angular.module("myApp",['ui.router']);
這里叫做App模塊痕支,這將告訴HTML頁(yè)面這是一個(gè)AgularJS作用的頁(yè)面,它的內(nèi)容有AngularJS引擎來(lái)解釋
2蛮原,這一行聲明了把$stateProvider和$urlRouterProvider路由引擎作為函數(shù)參數(shù)傳入卧须,這樣我們就可易為這個(gè)應(yīng)用程序配置路由了
myApp.config(function($stateProvider,$urlRouterProvider){
3,下面一行的意思是:如果沒(méi)有路由引擎能匹配當(dāng)前的導(dǎo)航狀態(tài)儒陨,那它就會(huì)默認(rèn)將路徑路由至PageTab.html花嘶,這個(gè)頁(yè)面就是狀態(tài)名稱被聲明的地方。只要理解了這個(gè)蹦漠,那么它就像switch case語(yǔ)句中的default選項(xiàng)
$urlRouterProvider.when("","/PageTab");
語(yǔ)句塊
1椭员,這一行定義了會(huì)在Main.html頁(yè)面第一個(gè)顯示出來(lái)的狀態(tài),作為頁(yè)面被加載好以后第一個(gè)被使用的路由
$stateProvide
????.state("PageTab",{
??????url:"/PageTab",
??????templateUrl:"PageTab.html"
????})
這就是向母版頁(yè)的子頁(yè)面笛园,應(yīng)用程序會(huì)首先加載這個(gè)main.html頁(yè)面
2隘击,現(xiàn)在,就由這一行來(lái)定義頁(yè)面研铆,但是埋同,這里又有點(diǎn)不同,我們之前為上面的狀態(tài)名稱加上了前綴蚜印,并且使用點(diǎn)"."號(hào)進(jìn)行了分隔莺禁,這里很關(guān)鍵,它會(huì)告訴路由引擎我們?cè)谶@里定義的是子頁(yè)面/嵌入頁(yè)面/嵌入狀態(tài)的page/route.
.state("PageTab.Page2",{
??????url:"/Page2",
??????templateUrl:"Page-2.html"
????})
它將會(huì)在"PageTab.html"頁(yè)面顯示出來(lái)窄赋,它的意思是:當(dāng)我們想要在母版頁(yè)中管理所有的頁(yè)面時(shí)哟冬,我們就會(huì)想要一個(gè)叫做"ui-view"的占位標(biāo)記楼熄。因此我們現(xiàn)在把PageTab.html佳作一個(gè)母版頁(yè),因?yàn)樗鼤?huì)把我們需要在PageTab.html中用"ui-view"聲明好的其它頁(yè)面都管理起來(lái)『葡浚現(xiàn)在我們?cè)賮?lái)修改這段代碼
PageTab.html
<div>
??<div>
????<span style="width:100px"><a href="">Page-1</a></span>
????<span style="width:100px"><a href="">Page-2</a></span>
????<span style="width:100px"><a href="">Page-3</a></span>
??</div>
??<div>
????<div ui-view="" />
??</div>
</div>
下面一行:
<div>
<div ui-view="">
</div>
也就是說(shuō)PageTab.html將對(duì)裝下所有的子頁(yè)面
現(xiàn)在一切就緒可岂,但是頁(yè)面應(yīng)該顯示哪個(gè)頁(yè)面呢。這就是我們要在路由引擎里面配置的東西翰灾,如下所示
.state("PageTab.Page2",{
??????url:"/Page2",
??????templateUrl:"Page-2.html"
????})
Page2.html將會(huì)在被叫做PageTab的狀態(tài)中顯示缕粹,它就是PageTab.html
??但是我們還落下啥事沒(méi)做,這事就是當(dāng)我們?cè)?Page-1 或者 Page-2 再或者 Page-3 菜單上點(diǎn)擊的時(shí)候需要頁(yè)面在占位標(biāo)記那里顯示出來(lái)纸淮,是不 ?
??還真是把那一塊給忘啦平斩,我們還沒(méi)有為路由和這種邏輯建立起聯(lián)系, 想象一下如果那是href的話,就意味著我們可以指定將會(huì)錨向頁(yè)面里面的ID名稱, 如果它是簡(jiǎn)單的html本地引用就是這樣咽块,但我們則需要按照需求顯示不同的頁(yè)面.
關(guān)鍵的地方在這里. (ui-sref) 我們需要再一次修改 PageTab.html绘面,如下所示.,
<div>
??<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>
</div>
注意,只是上面高亮的部分發(fā)生了改變 , 這里我們只是簡(jiǎn)單的將App.js中定義的狀態(tài)同tab中定義的對(duì)應(yīng)文本進(jìn)行了關(guān)聯(lián). 當(dāng)我們使用點(diǎn)符號(hào)對(duì)它進(jìn)行了聲明侈沪,程序就會(huì)認(rèn)為頁(yè)面時(shí)ui-view中的子頁(yè)面或者說(shuō)嵌入頁(yè)面揭璃,它們就是路由配置中需要被展示的頁(yè)面.
AngularJS ui-router-組件:
$state/$stateProvider:管理狀態(tài)定義,當(dāng)前狀態(tài)和狀態(tài)的轉(zhuǎn)換亭罪。包含觸發(fā)狀態(tài)轉(zhuǎn)換的事件和回調(diào)函數(shù)瘦馍,異步解決目標(biāo)狀態(tài)的任何依賴項(xiàng),更新$location到當(dāng)前狀態(tài)应役。由于狀態(tài)包含關(guān)聯(lián)的url情组,通過(guò)$urlRouterProvider生成一個(gè)路由規(guī)則來(lái)執(zhí)行轉(zhuǎn)換的狀態(tài)。
ui-view指示器:渲染狀態(tài)中定義的視圖扛吞,是狀態(tài)中定義的視圖的一個(gè)占位符呻惕。
$urlRouter/$urlRouterProvider:管理了一套路由規(guī)則列表來(lái)處理當(dāng)$location發(fā)生變化時(shí)荆责,如何跳轉(zhuǎn)滥比。最低級(jí)的方式是,規(guī)則可以是任意函數(shù)做院,來(lái)檢查$location盲泛,并在處理完成時(shí)返回true。支持正則表達(dá)式規(guī)則和通過(guò)$urlMatcherFactory編譯的UrlMatcher對(duì)象的url占位符規(guī)則键耕。
$urlMatcherFactory:將url和占位符編譯為UrlMatcher對(duì)象寺滚。除了$routeProvider支持的占位符語(yǔ)法之外,它還支持?jǐn)U展語(yǔ)言屈雄,允許一個(gè)正則表達(dá)式指定占位符村视,并且能夠提取命名參數(shù)和查詢url的一部分。$templateFactory-通過(guò)$http/$templateCache來(lái)加載模塊酒奶,供狀態(tài)配置中使用
關(guān)于嵌套路由
所謂嵌套路由蚁孔,就是視圖里還可以再嵌套視圖奶赔,路由里還可以在嵌套路由,并且通過(guò)ui-router杠氢,可以實(shí)現(xiàn)不同視圖之間的參數(shù)傳遞
關(guān)于ui-router的簡(jiǎn)單使用
ui-router定義路由的時(shí)候站刑,與ngRouter不一樣,它是使用.來(lái)進(jìn)行定義的鼻百,并且在html標(biāo)簽中绞旅,不使用ng-view,而是使用ui-view温艇,比如:<div ui-view></div>
ui-router提供了$stateProvider,$urlRouterProvider來(lái)定義路由因悲,具體使用如下:
/* 使用ui-router來(lái)進(jìn)行路由定義,需要注入ui.router模塊 */
var myApp = angular.module('myApp', ['ui.router']);
/* 注入$stateProvider勺爱,$urlRouterProvider */
myApp.config(['$stateProvider', '$urlRouterProvider', function ( $stateProvider, $urlRouterProvider ) {
/* 使用when來(lái)對(duì)一些不合法的路由進(jìn)行重定向 */
$urlRouterProvider.when('', '/main');
/* 通過(guò)$stateProvider的state()函數(shù)來(lái)進(jìn)行路由定義 */
$stateProvider.state('main', {
url: '/main',
templateUrl: 'views/main.html',
controller: 'MainCtrl'
}).state('detail', {
url: '/main/detail/store',
templateUrl: 'views/detail.html',
controller: 'DetailCtrl'
})
$stateProvider.state('404', {
url: '/404',
templateUrl: '404.html'
})
}]);
ui-router-路由控制$stateProvider
在我們的應(yīng)用中大多數(shù)狀態(tài)都有與其相關(guān)聯(lián)的url囤捻,路由控制不是設(shè)計(jì)完成state之后的事后想法,而是在開始開發(fā)時(shí)就應(yīng)該考慮的問(wèn)題
如何設(shè)置一個(gè)基本的url:
$stateProvider
.state('contacts',{
url:"/contacts",
templateUrl:'contacts.html'
})
當(dāng)我們?cè)L問(wèn)index.html/contacts時(shí)邻寿,‘contacts’狀態(tài)將被激活蝎土,同時(shí)index.html中的ui-view將被‘contacts.html’填充⌒宸瘢或者誊涯,通過(guò)transitionTo('contacts')方法將狀態(tài)轉(zhuǎn)變到‘contacts’狀態(tài),同時(shí)url將更新為index.html/contacts蒜撮。
狀態(tài)被激活時(shí)暴构,它的模板會(huì)自動(dòng)插入到父狀態(tài)對(duì)應(yīng)的模塊中包含ui-view屬性的元素內(nèi)部。如果是頂層的狀態(tài)段磨,那么它的父模板就是index.html
激活狀態(tài)
有三種方法來(lái)激活狀態(tài):
1調(diào)用$state.go()方法取逾,這是一個(gè)高級(jí)的遍歷方法
2點(diǎn)擊包含ui-sref指令鏈接
3導(dǎo)航到與狀態(tài)相關(guān)連的url
Templates模塊
可以通過(guò)下面幾種方式來(lái)配置一個(gè)狀態(tài)的模塊
方法一
配置template屬性,指定一段HTML字符串苹支,這是設(shè)置模塊的最簡(jiǎn)單打方式
$stateProvider.state('contact',{
template:'<h1>my contacts<h1>'
})
方法二
配置templateUrl屬性砾隅,來(lái)加載到指定位置的模塊,這就是設(shè)置模塊的常用方法
$stateProvider.state('contacts',{
templateUrl:'contacts.html'
})