AngularJS ui-router (嵌套路由)
AngularJS ui-router (嵌套路由)
介紹
AngularJS 嵌套路由:這是我針對同一個主題(ui-router)的第二篇文章. 如果你對第一篇文章感興趣的話,可以訪問 這里. 好了,讓我們繼續吧,來看看嵌套的ui-router狀態是怎么回事. ui-router和同屬AngularJS框架一部分的ng-route一樣強大. ui-router提供了讓我們可以做路由嵌套和視圖命名的特性. 我們將在示例中看到ui-router中存在的所有類型.
背景
引述我之前那篇文章開頭給出的使用ui-router框架實現的簡單路由, 基于我們的業務需求,需要有不同類型的導航, 一般像那種從一個頁面到另外一個頁面的導航非常的普通。但請想象一下在某些情況下,你需要在一個主頁中有tab頁或者菜單可以點擊打開相應的頁面.
好吧,讓我們來看看一個典型的導航..
注意,這個導航我們已經在之前的文章中見過。針對現在的主題我們將看到該導航嵌套進視圖中的形式.
根據上的界面設計,我們計劃該頁面能從一個頁面導航到另外一個頁面, 當點擊page-1時,我們將在下面顯示page-1的內容,點擊其它導航菜單也會有類似的效果. 我們希望這能夠用一種很直接的方式被處理. 讓我們開始寫代碼吧.
實戰
針對該需求我們使用AngularJS框架來創建簡單的html和JavaScript頁面. 我們將創建3個HTML頁面和一個JavaScript腳本文件。
一開始我們創建一個空的web應用程序,并加入三個HTML頁面。如下所示. 這些頁面都是片段視圖, 它們會在導航過程中展示。我們還要為了能展示應用程序的Tab,創建另外一個叫做PageTab.html的頁面.
因此我們需要創建以下文件:
1. Page1.html
2. Page2.html
3. Page3.html
4. PageTab.html
注意:我們使用的是AngularJS 1.2,當我寫這篇文章的時候,Angular 1.3已經發布了。
Page1.html
創建如下的html頁面:
<div> <div> <h1>Page 1 content goes here...</h1> </div> </div>
Page2.html
創建如下的html頁面:
<div> <div> <h1>Page 2 content goes here...</h1> </div> </div>
Page3.html
創建如下的html頁面:
<div> <div> <h1>Page 3 content goes here...</h1> </div> </div>
創建如下的html頁面:
PageTab.html
創建如下的html頁面:
<div> <div> <span style="width:100px">Page-1</span> <span style="width:100px">Page-2</span> <span style="width:100px">Page-3</span> </div> </div>
這將會使頁面文本處于側邊,哎呀,我忘了添加當用戶將鼠標懸停在文本上的時候的超鏈接了。讓我們這樣做:
<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>
我們沒有指向任何超鏈接,只是為了把鏈接放在href中,實際上這是一種獲取url的解決方法。
注意,到目前為止,我們還沒有插入任何AngularJS路由或者其它任何框架。目前我們只是創建了一些頁面片段,我們需要一個占位或者說父頁面來裝下這些東西. 讓我們把這個頁面叫做 Main.html.
現在我們就來創建它.
Main.html
用如下內容創建這個html頁面.
<!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"> <h1>AngularJS Home Page (Ui-router Demonstration)</h1> <div data-ui-view=""></div> </body> <html>
我們需要在主頁中做一些事情, (i) 我們需要引入AngularJS框架 (ii) 我們需要引入ui-router框架. (iii) 引入AngularJS文件 App.js (之后我會談到這個) (iv) 第四件事情就是讓主頁內容展示出來,然后顯示出它里面的頁面.
現在,讓我們看一下App.JS文件的內容,我們聲明了AngularJS模塊和路由配置。當頁面加載的時候我們會在Main.html中顯示PageTab.html的內容。代碼如下:
App.js
var myApp = angular.module("myApp", ['ui.router']); myApp.config(function ($stateProvider, $urlRouterProvider) { $urlRouterProvider.when("", "/PageTab"); $stateProvider .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: "Page3.html" }); });
我們一步步地來解釋這做了什么。
Line-1: 第一行,聲明AngularJS模塊, 并把ui-router傳入AngularJS主模塊,所有的結合起來我們就得到了Angular模塊。
var myApp = angular.module("myApp", ['ui.router']);
這里叫做App模塊,這將告訴HTML頁面這是一個AngularJS作用的頁面,它的內容由AngularJS引擎來解釋。
代碼行-2:這一行聲明了把 $stateProvider 和 $urlRouteProvider 路由引擎作為函數參數傳入,這樣我們就可以為這個應用程序配置路由了.
myApp.config(function ($stateProvider, $urlRouterProvider) {
代碼行-3: 好,那這一行做什么的呢,如果沒有路由引擎能匹配當前的導航狀態,那它就會默認將路徑路由至 PageTab.html, 這個頁面就是狀態名稱被聲明的地方. 只要理解了這個,那它就像switch case語句中的default選項.
$urlRouterProvider.when("", "/PageTab");
語句塊-1: 這一行定義了會在main.html頁面第一個顯示出來的狀態,作為頁面被加載好以后第一個被使用的路由.
$stateProvider .state("PageTab", { url: "/PageTab", templateUrl: "PageTab.html" })
這就向母版頁的子頁面,應用程序會首先加載這個main.html頁面。
語句塊-2: 現在,就由這一行來定義頁面, 但是等一等,這里有點不同,我們之前為上面的狀態名稱加上了前綴,并且使用點“.“號進行了分隔. 這里很關鍵,它會告訴路由引擎我們在這里定義的是子頁面/嵌入頁面/嵌入(sub page / nested page / nested)狀態的page/route.
.state("PageTab.Page1", { url:"/Page1", templateUrl: "Page-1.html" })
它將會在 "PageTab.html" 頁面里面顯示出來,那么它是什么意思呢. 想象一下當我們想要在母版頁中管理所有的頁面時,我們就會想要一個叫做”ui-view“的占位標記, 因此我們現在把PageTab.html叫做一個母版頁,因為它會把我們需要在PageTab.html中用”ui-view“ 聲明好的其它頁面都管理起來. 現在讓我們來修改一下它.
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>
也就是說 PageTab.html 將對裝下所有的子頁面.
現在一切就緒了。OK,可是現在誰來告訴程序應該顯示哪個頁面呢. 這就是我們要在路由引擎里面配置的東西,如下所示.
.state("PageTab.Page2", { url:"/Page2", templateUrl: "Page2.html" })
Page2.html 將會在被叫做PageTab的狀態中展示,它就是 PageTab.html.
Ok, 但是我們還落下啥事沒做,這事就是當我們在 Page-1 或者 Page-2 再或者 Page-3 菜單上點擊的時候需要頁面在占位標記那里顯示出來,是不 ?
還真是把那一塊給忘啦,我們還沒有為路由和這種邏輯建立起聯系, 想象一下如果那是href的話,就意味著我們可以指定將會錨向頁面里面的ID名稱, 如果它是簡單的html本地引用就是這樣,但我們則需要按照需求顯示不同的頁面.
關鍵的地方在這里. (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>
注意,只是上面高亮的部分發生了改變 , 這里我們只是簡單的將App.js中定義的狀態同tab中定義的對應文本進行了關聯. 當我們使用點符號對它進行了聲明,程序就會認為頁面時ui-view中的子頁面或者說嵌入頁面,它們就是路由配置中需要被展示的頁面.
現在,我們要看看目前為止我們討論過的那些頁面的內容了.
Main.html
<!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"> <h1>AngularJS Home Page (Ui-router Demonstration)</h1> <div data-ui-view=""></div> </body> <html>
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>
Page1.html
<div> <div> <h1>Page 1 content goes here...</h1> </div> </div>
Page2.html
<div> <div> <h1>Page 1 content goes here...</h1> </div> </div>
Page2.html
<div> <div> <h1>Page 1 content goes here...</h1> </div> </div>
App.js
var myApp = angular.module("myApp", ['ui.router']); myApp.config(function ($stateProvider, $urlRouterProvider) { $urlRouterProvider.when("", "/PageTab"); $stateProvider .state("PageTab", { url: "/PageTab", templateUrl: "PageTab.html" }) .state("PageTab.Page1", { url:"/Page1", templateUrl: "Page1.html" }) .state("PageTab.Page2", { url:"/Page2", templateUrl: "Page2.html" }) .state("PageTab.Page3", { url:"/Page3", templateUrl: "Page3.html" }); });
一切OK,現在讓我們把這個應用程序運行起來吧.