AngularJS學(xué)習(xí)--UI-Router

什么是UI-Router?

AngularJS 是一種富客戶端單頁(yè)面應(yīng)用框架,所以要在一個(gè)頁(yè)面呈現(xiàn)不同的視圖,路由起到了至關(guān)重要的作用。 UI-Router是Angular-UI提供的客戶端路由框架,它解決了原生的ng-route的不足(視圖不能嵌套,同一URL下不支持多個(gè)視圖)。例如實(shí)際的單頁(yè)面應(yīng)用中,導(dǎo)航欄用一個(gè)視圖,內(nèi)容部分用另一個(gè)視圖,就是比較常見(jiàn)的。
UI-Router提出了$state的概念。一個(gè)$state是一個(gè)當(dāng)前導(dǎo)航和UI的狀態(tài),每個(gè)$state需要綁定一個(gè)URL Pattern。 在控制器和模板中,通過(guò)改變$state來(lái)進(jìn)行URL的跳轉(zhuǎn)和路由。

如何使用UI-Router

UI-Router模塊是一個(gè)可選的angularJS模塊,如果需要使用,我們要單獨(dú)引用js。具體應(yīng)用示例如下:

<html>
  <head>
    <script src="lib/angular.js"></script>
    <script src="lib/angular-ui-router.js"></script>
    <script src="helloworld.js"></script>
    <style>.active { color: red; font-weight: bold; }</style>
  </head>
  <body ng-app="helloworld">
    <a ui-sref="hello" ui-sref-active="active">Hello</a>
    <a ui-sref="about" ui-sref-active="active">About</a>
    <ui-view></ui-view>
  </body>
</html>
var myApp = angular.module('helloworld', ['ui.router']);

myApp.config(function($stateProvider) {
  var helloState = {
    name: 'hello',
    url: '/hello',
    template: '<h3>hello world!</h3>'
  }

  var aboutState = {
    name: 'about',
    url: '/about',
    template: '<h3>Its the UI-Router hello world app!</h3>'
  }

  $stateProvider.state(helloState);
  $stateProvider.state(aboutState);
});

路由加載的三種方法

//1、·調(diào)用$state.go方法   
$state.go('detail', {id: 1});   
$state.go(“index');

//2、點(diǎn)擊包含ui-sref指令的鏈接
<a ui-sref="contacts">Contacts</a>
<a ui-sref="contacts.detail({contactId: 42})">Contact 42</a>
 
//3、url跳轉(zhuǎn)
<a href="#/index" >index</a>

視圖嵌套

ui-router的視圖可以嵌套,視圖嵌套通常對(duì)應(yīng)著$state的嵌套。 index.detail是index的子$state,index_detail.html也將作為index.html的子頁(yè)面。ui-view可以配合$state進(jìn)行任意層級(jí)的嵌套, 即index_detail.html中仍然可以包含一個(gè)ui-view,它的$state可能是index.detail.hobbies。

視圖命名

在ui-router中,一個(gè)$state下可以有多個(gè)視圖,它們有各自的模板和控制器。如上面的示例代碼,hello和about就是兩個(gè)獨(dú)立的視圖,有各自的末班和控制器。

參數(shù)說(shuō)明:

  • url:默認(rèn)相對(duì)路徑(以^開(kāi)頭的是絕對(duì)路徑)
  • views:每個(gè)子視圖可以包含自己的模板、控制器和預(yù)載入數(shù)據(jù)。 (后2項(xiàng)選填,控制器可以在view中綁定)
  • abstract:抽象模板不能被激活
  • template: HTML字符串或者返回HTML字符串的函數(shù)
  • templateUrl: HTML模板的路徑或者返回HTML模板路徑的函數(shù)
  • templateProvider:返回HTML字符串的函數(shù)
  • controller、controllerProvider:指定任何已經(jīng)被注冊(cè)的控制器或者一個(gè)作為控制器的函數(shù)
  • resolve:在路由到達(dá)前預(yù)載入一系列依賴或者數(shù)據(jù),然后注入到控制器中。
  • data:數(shù)據(jù)不會(huì)被注入到控制器中,用途是從父狀態(tài)傳遞數(shù)據(jù)到子狀態(tài)。
  • onEnter/onExit:進(jìn)入或者離開(kāi)當(dāng)前狀態(tài)的視圖時(shí)會(huì)調(diào)用這兩個(gè)函數(shù).
  • resolve 為控制器提供可選的依賴注入項(xiàng)。是由 key/value 組成的鍵值對(duì)象。
    key – {string}:注入控制器的依賴項(xiàng)名稱。
    value - {string|function}:
    string:一個(gè)服務(wù)的別名
    function:函數(shù)的返回值將作為依賴注入項(xiàng),如果函數(shù)是一個(gè)耗時(shí)的操作,那么控制器必須等待該函數(shù)執(zhí)行完成(be resolved)才會(huì)被實(shí)例化。
    比如,視圖都需要用戶登錄后才能訪問(wèn),那么判斷是否登錄就可以做成一個(gè)控制器依賴
    resolve: {authentication:['topicAuth', '$q', function(topicAuth, $q){ return $q.when().then(function(){ return topicAuth.authentication(); }); }]}

動(dòng)態(tài)加載模板/內(nèi)容

在實(shí)際使用時(shí)往往需要根據(jù)參數(shù)動(dòng)態(tài)加載不同模板/內(nèi)容。此時(shí)可以通過(guò)如下兩種方式實(shí)現(xiàn)。

//1、用參數(shù)作為文件名,拼接文件名加載
templateUrl: function ($stateParams){
    return '/topic/detail_' + $stateParams.type + '.html';
}
  
//2、用參數(shù)賦值,修改內(nèi)容
templateProvider: function ($timeout, $stateParams) {
    return $timeout(function () {
        return '<h1>' + $stateParams.topicId + '</h1>'
  }, 100);
}

路由參數(shù):

ui-router同樣支持切換視圖時(shí)傳遞參數(shù)。默認(rèn)有如下兩種方式傳遞參數(shù):

  1. 通過(guò)$stateParams傳遞。傳遞的參數(shù)是一個(gè)object。傳遞的方法有:
    • ui-sref="index.detail({id:22})“
    • $state.go('index.detail', {id: 22});
  2. 通過(guò)$location來(lái)獲取和設(shè)置URL。直接在controller里引入$stateParams 和$location即可。

state 為view controller提供自定義數(shù)據(jù)。

$stateProvider.state(‘blog.index', {
        templateUrl: ’templates/blog_index.html',
        data: {
            currentPage: 1,
            pageSize: 20
        } 
    })

上面 data 對(duì)象就是自定義數(shù)據(jù),里面定義了頁(yè)面的當(dāng)前頁(yè)和顯示內(nèi)容條數(shù)。在視圖對(duì)應(yīng)的 controller 中我們就可以通過(guò)下面的方法來(lái)獲取自定義數(shù)據(jù).

    console.log($state.current.data.currentPage);  // 1
    console.log($state.current.data.pageSize);  // 20

如何判斷選中視圖選中

  1. $state.includes
    返回 true / false,查看當(dāng)前狀態(tài)是否在某父狀態(tài)內(nèi),比如 $state.includes('contacts')
    <!-- 包含在 /contacts 狀態(tài)內(nèi)部,即其作為 parant state -->
    <li ng-class="{active: $state.includes('contacts')}">
        <a ui-serif="contacts.list">Contacts</a>
    </li>
    
  2. ui-sref-active
    查看當(dāng)前激活狀態(tài)并設(shè)置 Class。例如
    <li ui-sref-active="active"><a ui-sref="about">About</a></li>
    

控制器引入的集中方法

$stateProvider.state('contacts', {//直接定義
  template:'<h1>test</h1>',
  controller: function($scope){
    $scope.title = 'My Contacts';
  }
}).state('contacts1', {//直接名稱引用
  template:'<h1>test</h1>',
  controller: 'ContactsCtrl'
}).state('contacts2', {//直接定義并且定義別名
  template:'<h1>test</h1>',
  controller: function(){
    this.title = 'My Contacts';
  },
  controllerAs: 'contact'
}).state('contacts3', { //控制器名稱并且定義別名
  template:'<h1>test</h1>',
  controller: 'ContactsCtrl as contact'
}).state('contacts4', { //根據(jù)state動(dòng)態(tài)加載
  template:'<h1>test</h1>',
  controllerProvider: function($stateParams) {
      var ctrlName = $stateParams.type + "Controller";
      return ctrlName;
  }
});

注意:如果未定義template,controller將不會(huì)被實(shí)例化
更多說(shuō)明:參考 https://github.com/angular-ui/ui-router/wiki

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容