天天看點

Angularjs學習筆記--ui-RouterAngularjs ui-router - 元件:事件總結 大部分為摘抄别人的,做個說明免得被人吐槽。

Angularjs ui-router - 元件:

  • $state / $stateProvider:管理狀态定義、目前狀态和狀态轉換。包含觸發狀态轉換的事件和回調函數,異步解決目标狀态的任何依賴項,更新

    $location

    到目前狀态。由于狀态包含關聯的 url,通過$urlRouterProvider生成一個路由規則來執行轉換的狀态。
  • ui-view訓示器:渲染狀态中定義的視圖,是狀态中定義的視圖的一個占位符。
  • $urlRouter / $urlRouterProvider:管理了一套路由規則清單來處理當

    $location

    發生變化時如何跳轉。最低級的方式是,規則可以是任意函數,來檢查

    $location

    ,并在處理完成時候傳回

    true

    。支援正規表達式規則和通過

    $urlMatcherFactory

    編譯的

    UrlMatcher

    對象的 url 占位符規則。
  • $urlMatcherFactory:将 url和占位符編譯為

    UrlMatcher

    對象。除了

    $routeProvider

    支援的占位符文法之外,它還支援擴充文法,允許一個正規表達式指定占位符,并且能夠提取命名參數和查詢url的一部分。
  • $templateFactory - 通過

    $http

     / 

    $templateCache

    來加載模闆,供狀态配置中使用。

AngularJS不需要任何第三方庫,利用自身內建的各個子產品便可開發出功能齊全的web應用,不過活躍的AngularJS社群也開發了很多能夠最大限度強化web應用的程式設計庫。本文帶讀者了解專業開發使用的子產品AngularUI中的ui-路由(ui-router)。AngularUI庫已經被分成了幾個子產品,使用者可以隻選擇載入自己感興趣的子產品,而不用載入整個庫。

UI-Router

UI-Router被認為是AngularUI為開發者提供的最實用的一個子產品,它是一個讓開發者能夠根據URL狀态或者說是'機器狀态'來組織和控制界面UI的渲染,而不是僅僅隻改變路由(傳統AngularJS應用實用的方式)。該子產品為開發者提供了很多最視圖(view)額外的控制。開發者可以建立嵌套分層的視圖、在同一個頁面使用多個視圖、讓多個視圖控制某個視圖等更多的功能。即使是非常複雜的web應用,UI-Router也可以極佳地駕馭。

安裝

安裝方式可以選擇下載下傳發行版本或者使用Bower(前端包管理器):

$ bower install angular-ui-router --save
           

同時也需要将源檔案包含到頁面中:

接下來,将UI-Router作為web應用的依賴,注入到主程式:

與內建的ngRoute服務不同的是,UI-Router可以将視圖嵌套,因為它基于的是操作狀态而僅非URL。與傳統做法使用ng-view不同的是,在ngRoute裡需要使用ui-view服務。當在ui-router中處理路由和狀态時,開發者的重心是目前的狀态是什麼以及在哪一個頁面裡。

和ngRoute一樣,為特定狀态指定的模闆将會放在

<div ui-view></div>

元素中。在這些模闆中也可以包含自己的

ui-view

,這就是在同一個路由下實作嵌套視圖的方法。要定義一個路由,與傳統的方法相同:使用

.config

方式,但使用的不是

$routeProvider

而是

$stateProvider

上述代碼在設定對象上定義了一個叫

start

的狀态。設定對象

stateConfig

和路由設定對象的選項是非常相似的。

模闆,模闆路徑,模闆Provider

開發者可以在每個視圖下使用如下方式來設定模闆 - template - HTML字元串,或者是傳回HTML字元串的函數 - templateUrl - HTML模闆的路徑,或者是傳回HTML模闆路徑的函數 - templateProvider - 傳回HTML字元串的函數 例如:

控制器

ngRoute

相似,開發者可以指定任何已經被注冊的控制器,或者在路由裡面建立一個作為控制器的函數。但如果沒有定義模闆,控制器将無效。

預載入Resolve

使用預載入功能,開發者可以預先載入一系列依賴或者資料,然後注入到控制器中。在

ngRoute

resolve

選項可以允許開發者在路由到達前載入資料保證(promises)。在使用這個選項時比使用angular-route有更大的自由度。

預載入選項需要一個對象,這個對象的key即要注入到控制器的依賴,這個對象的value為需要被載入的

factory

服務。

如果傳入的時字元串,angular-route會試圖比對已經注冊的服務。如果傳入的是函數,該函數将會被注入,并且該函數傳回的值便是控制器的依賴之一。如果該函數傳回一個資料保證(promise),這個資料保證将在控制器被執行個體化前被預先載入并且資料會被注入到控制器中。

URL

url選項将會為該應用的狀态指定一個URL基于使用者浏覽該應用所在的狀态。這樣當在浏覽該應用的時候便能實作

深度連結

的效果。 該選項與ngRoute的URL相似,但可以被視為對ngRoute主要的更新,在接下來的文章裡你便會認可這一點。開發者可以這樣指定一個基本的路由。

$stateProvider
      .state('inbox', { url: '/inbox', template: '<h1>Welcome to your inbox</h1>' });                

當使用者浏覽到

/inbox

時,該應用将狀态改為

inbox

同時向主ui-view元素中插入模闆中的内容('Welcome to your inbox')。URL參數有多個選項,是以它非常強大。開發者可以像設定ngRoute一樣設定最基本的參數:

$stateProvider
      .state('inbox', { url: '/inbox/:inboxId', template: '<h1>Welcome to your inbox</h1>', controller: function($scope, $stateParams) { $scope.inboxId = $stateParams.inboxId; } });                

現在将

:inboxId

最為URL的第二個部分,例如:通路/inbox/1,那麼

$stateParams.inboxId

就為1($stateParams為{inboxId:1})。同時也可使用不同的文法:

路徑必須比對URL,與ngRoute不同的是,當使用者通路到

/inbox/

時,上面的的路徑會被激活,然而當通路到

/inbox

時不會被激活。路徑同時也使開發者可以使用正規表達式來比對,例如:

// 限定id為6位16進制數字
    url: '/inbox/{inboxId:[0-9a-fA-F]{6}}',  // 或者  // 比對任何在 `/inbox`後面的url(慎用)并比對值到indexId url: '/inbox/{inboxId:.*}'                
注意,在路由中目前還無法使用路由組,路由資料預載入器無法預載入。

在路徑裡也可以指定查詢參數:

// /inbox?sort=ascending 将會被比對
    url: '/inbox?sort'                

嵌套路由

使用url參數可以實作嵌套的路由,有了嵌套路由便可在同一個模闆同一個路由實作多層次的ui-view,例如在/inbox中嵌入更多路由:

$stateProvider
      .state('inbox', { url: '/inbox/:inboxId', template: '<div><h1>Welcome to your inbox</h1>\ <a ui-sref="inbox.priority">Show priority</a>\ <div ui-view></div>\ </div>', controller: function($scope, $stateParams) { $scope.inboxId = $stateParams.inboxId; } }) .state('inbox.priority', { url: '/priority', template: '<h2>Your priority inbox</h2>' });                

第一個路由是傳統的,注意第二個,它是/inbox下的一個子路由:state( . )文法指定了它使子路由。

/inbox/1

将比對第一個路由,而

/index/1/priority

會比對第二個路由。使用這種文法,在父視圖中的ui-view元素将會由第二個路由控制。

Params 路由參數

params選項是一個包含路徑中的參數和正規表達式比對結果的數組。該選項不能和url選項混用!當某狀态被激活時,應用将這個數組指派給

$stateParams

服務。

Views 視圖

開發者可以在一個狀态中設定多個有名稱的視圖。該功能在ui-router中很強大,開發者可以在同一個模闆中改變和切換不同的視圖。

<如果設定了視圖選項,則該狀态的‘template’,‘templateUrl’及‘templateProvider’将被忽略。如果想在路由裡包含父級模闆,就需要建立一個包含模闆的抽象模闆。

例如有這樣的視圖:

<div>
  <div ui-view="filters"></div> <div ui-view="mailbox"></div> <div ui-view="priority"></div> </div>
           

接下來就可以建立将被分别被插入到上述ui-view的有命名的視圖了,每個子視圖可以包含自己的模闆、控制器和預載入資料。

$stateProvider
  .state('inbox', { views: { 'filters': { template: '<h4>Filter inbox</h4>', controller: function($scope) {} }, 'mailbox': { templateUrl: 'partials/mailbox.html' }, 'priority': { template: '<h4>Priority inbox</h4>', resolve: { facebook: function() { return FB.messages(); } } } } });                

abstract 抽象模闆

抽象模闆不能被激活,但是它的子模闆可以被激活。抽象模闆可以提供一個包括了多個有名的視圖的模闆,或者它可以傳遞作用域變量$scope給子模闆。使用它可以在同一個url下傳遞自定義資料或者預載入的依賴。除了需要添加

abstract

屬性外,其他設定和設定一個正常狀态是相同的:

$stateProvider
  .state('admin', { abstract: true, url: '/admin', template: '<div ui-view></div>' }) .state('admin.index', { url: '/index', template: '<h3>Admin index</h3>' }) .state('admin.users', { url: '/users', template: '<ul>...</ul>' });                

onEnter,onExit 回調函數

當應用進入或者離開目前狀态的視圖時會調用這兩個函數。這兩個函數可以通路預載入的資料。這兩個回調函數使開發者可以根據狀态改變來采取某些動作,例如在使用者要離開時可以彈出對話框‘你确定嗎?’以及防止意外操作等。

Data 資料

自定義資料也可以被附加到狀态控制對象state configObject.該資料和預載入資料resolve屬性相似,但是該資料不會被注入到控制器中,promise也不會被預載入,它的用途是從父狀态傳遞資料到子狀态。

事件

和ngRoute相同的是,angular-route服務會在不同的狀态生命周期lifecycle裡啟動某些事件events。監聽$scope對象便可以捕獲這些事件然後采取不同的響應或者操作。如下的事件将會在

$rootScope

上觸發,是以在任何$scope對象上都可以監聽到這些事件。

狀态改變事件

可以觸發的事件包括:

stateChangeStart

當狀态改變開始的時候被觸發

$stateChangeSuccess

當狀态改變成功後被觸發

$stateChangeError

當狀态改變遇到錯誤時被觸發,錯誤通常是目标無法載入,需要預載入的資料無法被載入等。

視圖載入事件

視圖載入階段ui-router也提供了一些事件

$viewContentLoading

當視圖正在被載入且在DOM被渲染之前觸發。

$viewContentLoaded

當視圖被載入且DOM已經渲染完成後被觸發。

$stateParams 狀态參數

在上面提及使用$stateparams來提取在url中的不同參數。該服務的作用是處理url的不同部分。例如,當上述的inbox狀态是這樣時:

url: '/inbox/:inboxId/messages/{sorted}?from&to'

//當使用者通路者連結時:
'/inbox/123/messages/ascending?from=10&to=20'                

$stateParams

對象的值為:

{inboxId: '123', sorted: 'ascending', from: 10, to: 20}
           

$urlRouterProvider

和ngRoute一樣,開發者可以在該對象上設定特定的URL被激活時做什麼的規則。由于設定好的狀态在特定的url被通路是會自動激活,是以$urlRouterProvider沒有必要用來管理激活和載入狀态。但當需要管理哪些被發生在目前狀态之外的作用域scope時它會非常有用,例如在重定向或者安全驗證的時候。在子產品的設定函數裡便可使用$urlRouterProvider。

when()

該函數需要兩個參數:1.目前的路徑,2.需要重定向到的路徑(或者是需要在路徑被通路是運作的函數)。設定重定向前需要為$urlRouterProvider設定when函數來接受一個字元串。例如,當希望重定向一個空的路由到/inbox:

如果傳遞的是函數,在路徑被比對時該函數會被執行,處理器傳回如下3個值中的一個: - falsy,該回應告訴$urlRouter沒有比對到目前url規則,應該嘗試比對新的路徑,這樣能保證使用者通路了正常的路徑。 - 字元串,$urlRouter将該字元串當做重定向的路徑。 - TRUE 或者 undefined,該回應告訴$urlRouter,url已被處理

otherwise()

和ngRoute的otherwise()函數相似,在使用者送出的路徑沒有被定義的時候它将重定向到指定的頁面。這是個建立’預設‘路徑的好方法。 otherwise()隻接受一個參數,要麼函數要麼字元串,字元串必須為合法的url路由位址,函數則會在沒有任何路徑被比對的時候被運作。

rule()

如果想越過任何URL的比對或者在其他路由前做路由修改,則可以使用rule()函數。在使用它的時候必須傳回一個合法的代表路徑的字元串。

總結

本文涵蓋了ui-router深度及幾乎全部的功能。希望你也發現這個庫的強大和實用,并在下一個項目中實用這些強大的功能。

大部分為摘抄别人的,做個說明免得被人吐槽。