【修真院web小課堂】如何使用UI-ROUTER?

? ? ? ?大家好,我是IT修真院北京分院第23期的學(xué)員郭婷婷,一枚正直純潔善良的WEB前端程序員。

? ? ? ?今天給大家分享一下,如何使用UI-ROUTER?

? ? ? ?分享人:郭婷婷

1.背景介紹

? ? ? ? ? ? ? ? ? ? Angular.js有內(nèi)置的路由模塊:叫做ngRoute。但是事實(shí)卻是許多開發(fā)者卻不使用其內(nèi)置的路由模塊,而是使用一個(gè)基于ngRoute開發(fā)的第三方路由模塊

? ? ? ? ? ? ? ? ? ? (UI-Router模塊)來代替。

2.知識(shí)剖析

? ? ? ? ? ? ? ? ? var myApp = angular.module("myApp", [ui.router]);

? ? ? ? ? ? ? ? ? myApp.config(function ($stateProvider, $urlRouterProvider) {

? ? ? ? ? ? ? ? ? $urlRouterProvider.when("", "/PageTab");

第一行,聲明AngularJS模塊, 并把ui-router傳入AngularJS主模塊,所有的結(jié)合起來我們就得到了Angular模塊。

? ? ? ? ? ? ? ? 第二行聲明了把 $stateProvider 和 $urlRouteProvider 路由引擎作為函數(shù)參數(shù)傳入,這樣我們就可以為這個(gè)應(yīng)用程序配置路由了.

? ? ? ? ? ? ? ? 第三行,如果沒有路由引擎能匹配當(dāng)前的導(dǎo)航狀態(tài),那它就會(huì)默認(rèn)將路徑路由至 PageTab.html, 這個(gè)頁面就是狀態(tài)名稱被聲明的地方。

? ? ? ? ? ? ? ? ? ? .state("PageTab", {

? ? ? ? ? ? ? ? ? ? ? ? url: "/PageTab",

? ? ? ? ? ? ? ? ? ? ? ? templateUrl: "PageTab.html"

? ? ? ? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? ? ? .state("Page", {

? ? ? ? ? ? ? ? ? ? ? ? url: "/Page",

? ? ? ? ? ? ? ? ? ? ? ? template: 'hello world'

? ? ? ? ? ? ? ? ? ? ? })

template, 字符串方式的模板內(nèi)容,或者是一個(gè)返回 HTML 的函數(shù)

templateUrl, 模板的路徑,或者返回模板路徑的函數(shù)

url選項(xiàng)將會(huì)為該應(yīng)用的狀態(tài)指定一個(gè)URL基于用戶瀏覽該應(yīng)用所在的狀態(tài)。

$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,通過$urlRouterProvider生成一個(gè)路由規(guī)則來執(zhí)行轉(zhuǎn)換的狀態(tài)。

$urlRouter /

? ? ? ? ? ? ? ? ? ? $urlRouterProvider:管理了一套路由規(guī)則列表來處理當(dāng)$location發(fā)生變化時(shí)如何跳轉(zhuǎn)。最低級(jí)的方式是,規(guī)則可以是任意函數(shù),來檢查$location,并在處理完成時(shí)候返回true。支持正則表達(dá)式規(guī)則和通過$urlMatcherFactory編譯的UrlMatcher對(duì)象的

url 占位符規(guī)則。

ui-view指示器:渲染狀態(tài)中定義的視圖,是狀態(tài)中定義的視圖的一個(gè)占位符。

Views 視圖

? ? ? ? ? ? ? ? ? ? 開發(fā)者可以在同一個(gè)模板中改變和切換不同的視圖。如果設(shè)置了視圖選項(xiàng),則該狀態(tài)的‘template’,‘templateUrl’及‘templateProvider’將被忽略。如果想在路由里包含父級(jí)模板,就需要?jiǎng)?chuàng)建一個(gè)包含模板的抽象模板。例如:

? ? ? ? ? ? ? ? ? ? ?state('PageTab.uitest', {

? ? ? ? ? ? ? ? ? ? ? ? ? url: '/',

? ? ? ? ? ? ? ? ? ? ? ? ? views: {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? '': {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? template: 'hello world'

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 'status': {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? template: 'home page'

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? });

when()

該函數(shù)需要兩個(gè)參數(shù):1.當(dāng)前的路徑,2.需要重定向到的路徑(或者是需要在路徑被訪問是運(yùn)行的函數(shù))。設(shè)置重定向前需要為$urlRouterProvider設(shè)置when函數(shù)來接受一個(gè)字符串。例如,當(dāng)希望重定向一個(gè)空的路由到/inbox:

? ? ? ? ? ? ? ? $urlRouterProvider.when("","/pagedata");

otherwise()

和ngRoute的otherwise()函數(shù)相似,在用戶提交的路徑?jīng)]有被定義的時(shí)候它將重定向到指定的頁面。這是個(gè)創(chuàng)建’默認(rèn)‘路徑的好方法。

otherwise()只接受一個(gè)參數(shù),要么函數(shù)要么字符串,字符串必須為合法的url路由地址,函數(shù)則會(huì)在沒有任何路徑被匹配的時(shí)候被運(yùn)行。

? ? ? ? ? ? ? ? .config(function($urlRouterProvider) {

? ? ? ? ? ? ? ? ? $urlRouterProvider.otherwise('/');

? ? ? ? ? ? ? ? ? // or

? ? ? ? ? ? ? ? ? $urlRouterProvider.otherwise(

? ? ? ? ? ? ? ? ? ? function($injector, $location) {

? ? ? ? ? ? ? ? ? ? ? $location.path('/');

? ? ? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? });

3.常見問題

為什么大家更喜歡使用ui-router替代angular內(nèi)置的ngroute

? ? ? ? 這是因?yàn)閁I-Router有兩個(gè)重要的特性:

* 多視圖

* 嵌套視圖

4.解決方案

多視圖:頁面可以顯示多個(gè)動(dòng)態(tài)變化的不同區(qū)塊。

比如:頁面一個(gè)區(qū)塊用來顯示頁面狀態(tài),另一個(gè)區(qū)塊用來顯示頁面主內(nèi)容,當(dāng)路由切換時(shí),頁面狀態(tài)跟著變化,對(duì)應(yīng)的頁面主內(nèi)容也跟著變化。

? ? ? ? ? ? ? ? ? ? ? $routeProvider

? ? ? ? ? ? ? ? ? ? ? ? .when("/ngtest", {

? ? ? ? ? ? ? ? ? ? ? template: 'hello world'

? ? ? ? ? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? ? ? html中利用ng-view指令定義了兩個(gè)區(qū)塊,于是兩個(gè)div中顯示了相同的內(nèi)容,這很合乎情理,但卻不是我們想要的,但是又不能為力,因?yàn)椋趎gRoute中:

1、視圖沒有名字進(jìn)行唯一標(biāo)志,所以它們被同等的處理;

2、路由配置只有一個(gè)模板,無法配置多個(gè)。

? ? ? ? ? ? ? ? ? ? ? state('PageTab.uitest', {

? ? ? ? ? ? ? ? ? ? ? ? ? url: '/',

? ? ? ? ? ? ? ? ? ? ? ? ? views: {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? '': {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? template: 'hello world'

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 'status': {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? template: 'home page'

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? ? ? 兩個(gè)區(qū)塊,分別顯示了不同的內(nèi)容,原因在于,在ui.router中:

1、可以給視圖命名,如:ui-view=”status”。

2、可以在路由配置中根據(jù)視圖名字(如:status),配置不同的模板。

? ? ? ? ? ? ? ? ? ? 嵌套視圖:頁面某個(gè)動(dòng)態(tài)變化區(qū)塊中,嵌套著另一個(gè)可以動(dòng)態(tài)變化的區(qū)塊。

比如:頁面一個(gè)主區(qū)塊顯示主內(nèi)容,主內(nèi)容中的部分內(nèi)容要求根據(jù)路由變化而變化,這時(shí)就需要另一個(gè)動(dòng)態(tài)變化的區(qū)塊嵌套在主區(qū)塊中。

? ? ? ? ? ? ? ? ? ? 其實(shí),嵌套視圖,在html中的最終表現(xiàn)就像這樣:

? ? ? ? ? ? ? ? ? ? ? ? ? I am parent

? ? ? ? ? ? ? ? ? ? ? ? ?I am child

? ? ? ? ? ? ? ? ? ? 轉(zhuǎn)成javascript,我們會(huì)在程序里這樣寫:

? ? ? ? ? ? ? ? ? ? ? ? $routeProvider

? ? ? ? ? ? ? ? ? ? ? ? ? ? .when('/', {

template: 'I am parentI am child'

? ? ? ? ? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? ? ? 倘若,你真的用ngRoute這樣寫,你會(huì)發(fā)現(xiàn)瀏覽器崩潰了,因?yàn)樵趎g-view指令link的過程中,代碼會(huì)無限遞歸下去。

? ? ? ? ? ? ? ? ? ? 造成這種現(xiàn)象的最根本原因:路由沒有明確的父子層級(jí)關(guān)系!

? ? ? ? ? ? ? ? ? ? ? ? $stateProvider

? ? ? ? ? ? ? ? ? ? ? ? ? ? .state('parent', {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? abstract: true,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? url: '/',

template: 'I am parent'

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? ? ? ? ? ? ? .state('parent.child', {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? url: '',

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? template: 'I am child'

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? ? ? 1、通過parent與parent.child來確定路由的父子關(guān)系,從而解決無限遞歸問題。

2、另外子路由的模板最終也將被插入到父路由模板的div[ui-view]中去,從而達(dá)到視圖嵌套的效果。

5.編碼實(shí)戰(zhàn)

6.擴(kuò)展思考

state.go傳參

state.go跳轉(zhuǎn)頁面

? ? ? ? ? ? ? ? ? ? ? angular.module("myApp").controller("pagectrl",function ($scope,$state) {

? ? ? ? ? ? ? ? ? ? ? ? $scope.test = function () {

? ? ? ? ? ? ? ? ? ? ? ? ? ? $state.go('PageTab.Page1')

? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? })

state.go傳參

? ? ? ? ? ? ? ? ? ? //路由配置頁面

? ? ? ? ? ? ? ? ? ? .state("PageTab.Page1", {

? ? ? ? ? ? ? ? ? ? ? url:"/Page1:id",

? ? ? ? ? ? ? ? ? ? ? templateUrl: "Page1.html"

? ? ? ? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? ? ? //跳轉(zhuǎn)頁面

? ? ? ? ? ? ? ? ? ? angular.module("myApp").controller("pagectrl",function ($scope,$state) {

? ? ? ? ? ? ? ? ? ? ? ? $scope.test = function () {

? ? ? ? ? ? ? ? ? ? ? ? ? ? $state.go('PageTab.Page1',{"id":"test"})

? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? ? ? //跳轉(zhuǎn)目標(biāo)頁

? ? ? ? ? ? ? ? ? ? angular.module("myApp").controller("page1ctrl",function ($scope,$stateParams) {

? ? ? ? ? ? ? ? ? ? ? ? console.log($stateParams.id)

? ? ? ? ? ? ? ? ? ? ? ? ? })

7.參考文獻(xiàn)

AngularJS ui-router (嵌套路由)

ui.router源碼解析

8.更多討論


1、ui-sref 和 $state.go 的區(qū)別

ui-sref?一般使用在 <a>?標(biāo)簽上;而$state.go一般使用在?controller?里面。

2、$stateParams怎樣獲取參數(shù)?

在目標(biāo)頁面的controller里注入$stateParams,然后 "$stateParams.參數(shù)名" 獲取傳遞的參數(shù)。

3、UI-ROUTER如何設(shè)置?

這里是如何設(shè)置一個(gè)基本url。

$stateProvider

.state('contacts', {

url:"/contacts",

templateUrl:'contacts.html'

? ? })

當(dāng)我們?cè)L問index.html/contacts時(shí),'contacts'狀態(tài)將被激活,同時(shí)index.html中的ui-view將被'contacts.html'填充。或者,通過transitionTo('contacts')方法將狀態(tài)轉(zhuǎn)變到'contacts'狀態(tài),同時(shí) url 將更新為index.html/contacts。

鳴謝

感謝大家觀看

BY :郭婷婷

PPT鏈接:https://ptteng.github.io/PPT/PPT/js-06-ui-router-pek.html#/

視頻鏈接:https://v.qq.com/x/page/o0527550hgl.html

--------------------------------------------------------------------------------------------------------------------

技能樹.IT修真院

“我們相信人人都可以成為一個(gè)工程師,現(xiàn)在開始,找個(gè)師兄,帶你入門,掌控自己學(xué)習(xí)的節(jié)奏,學(xué)習(xí)的路上不再迷茫”。

這里是技能樹.IT修真院,成千上萬的師兄在這里找到了自己的學(xué)習(xí)路線,學(xué)習(xí)透明化,成長(zhǎng)可見化,師兄1對(duì)1免費(fèi)指導(dǎo)。快來與我一起學(xué)習(xí)吧?!

猛戳這里

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容