Angular-ui-router入門


什么是ui-router

  • ui-router是AngularUI庫最有用的組件之一(AngularUI庫由AngularJS社區構建)。它是一個第三方路由框架,允許通過狀態機制組織接口,而不是簡單的URL路由。

 作用

  •  和ngRoute功能一樣,可以定義在任意狀態內的模板都處在<ui-view>中
  •  與ngRoute不同的是,每個模板中可以包含自己的<ui-view>中,也就是我們說的嵌套路由

如何使用

  •    下面,將要向大家介紹下使用ui-router建立一個簡單的路由,涵蓋了ui-router基本的也是常用的方法。
  •    首先,需要定義路由,可以使用.config方法,和ngRoute不同的是,路由是要設置在$routeProvider上, 而是將狀態設置在$stateProvider上,

             $stateProvider.state(stateName, stateConfig)

             stateName::字符串

             stateConfig:object對象,可以設置url、template、controller等屬性

  •    了解完定義狀態的用法,我們可以看一下實例代碼:

 

 1 app.config(function($stateProvider) {
 2     $stateProvider
 3         .state('C1', {
 4             url:'/C1',
 5             template: '<h1>進入C1狀態</h1>'
 6 
 7         })
 8         .state('C2', {
 9             url: '/C2',
10             templateUrl: 'Htmls/C2.html'
11 
12         })
13         .state('C3', {
14             url: '/C3',
15             templateProvider: function() {
16                 return '<h1>進入C3狀態</h1>';
17             }
18         })
19 });

 

  • 上面代碼中,我們給狀態配置對象分配了三個狀態,“C1”、“C2”和"C3"。當應用程序狀態為以上三個狀態時,url會自動切換到定義的地址,而且也會顯示相應的html模板。其中,有三種顯示html模板的方式

           template: 一個html內容字符串或一個能返回html字符串的函數, 如狀態C1處代碼;

           templateUrl: 一個html模板的路徑字符串或者是一個能返回URL路徑字符串的函數,如狀態C2處代碼;

           templateProvider:一個能返回URL路徑字符串的函數,如狀態C3處代碼;

  • 現在,我們來寫一下index.html和app.js文件,實現一下ui-router:

      

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8" />
 5         <title>index</title>
 6         <link href="css/index.css" rel="stylesheet" />
 7         <script src="js/lib/angular/angular.min.js"></script>
 8         <script src="js/lib/angular-ui-router/release/angular-ui-router.min.js"></script>
 9         <script src="app.js"></script>
10     </head>
11     <body ng-app="TrialApp" ng-controller="mainController" style="background-color: lightblue;">
12         <h1>index頁面</h1>
13         <div style="width: 80%; float: right;background-color: #C0C0C0;">
14             <h1>路由區域</h1>
15             <ui-view> </ui-view>
16         </div>            
17     </body>
18 </html>

 

  • 建立一個定義TrialApp模塊文件app.js:
 1 'use strict';
 2 // Define `TrialApp` module
 3 var app = angular.module('TrialApp', ['ui.router']);
 4 // Define routers
 5 app.config(function($stateProvider) {
 6     $stateProvider
 7         .state('C1', {
 8             url:'/C1',
 9             template: '<h1>進入C1狀態</h1>'
10 
11         })
12         .state('C2', {
13             url: '/C2',
14             templateUrl: 'Htmls/C2.html'
15 
16         })
17         .state('C3', {
18             url: '/C3',
19             templateProvider: function() {
20                 return '<h1>進入C3狀態</h1>';
21             }
22         })
23 });
  •  這時,並不能一進入頁面就能看見路由的效果,需要我們通過寫代碼來激活狀態。激活state有3種方法:  

           1. 調用$state.go('stateName');方法;

           2. 在html文檔中<ui-view>區域之外的地方,添加<a ui-sref='stateName'>stateName</a>鏈接,等頁面渲染之后可以通過點擊該鏈接進入所選狀態所對應的頁面;

           3. 在地址欄中輸入state中定義過的url,隨后Enter直接訪問。

  •     現在我們來演示一下上述方法中的前面兩種激活狀態的方法:

           方法1: 如果需要在頁面一加載時就要顯示某一狀態,需要在app.js后面加一下代碼:

1 app.run(function($state) {
2     $state.go('C1');
3 });

 

          上述代碼是在加載該模塊的時候調用$state.go('C1');,以激活C1狀態。運行以后就是以下效果:

 

                        

       方法2:在html文檔中<ui-view>區域之外的地方,添加<a ui-sref='stateName'>stateName</a>鏈接,代碼如下:

  

1 <a ui-sref='C1'>C1</a><br />
2 <a ui-sref='C2'>C2</a><br />
3 <a ui-sref='C3'>C3</a>

      由於上述效果有點丑,我們調整下html代碼:

  

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8" />
 5         <title>index</title>
 6         <link href="css/index.css" rel="stylesheet" />
 7         <script src="js/lib/angular/angular.min.js"></script>
 8         <script src="js/lib/angular-ui-router/release/angular-ui-router.min.js"></script>
 9         <script src="app.js"></script>
10     </head>
11     <body ng-app="TrialApp" ng-controller="mainController" style="background-color: lavender;">
12         <h1>index頁面</h1>
13         <div style="width: 20%; float: left;background-color: lightgoldenrodyellow;text-align: center;">
14             <a ui-sref='C1'>C1</a><br />
15             <a ui-sref='C2'>C2</a><br />
16             <a ui-sref='C3'>C3</a>
17         </div>
18         <div style="width: 80%; float: right;background-color: #C0C0C0;">
19             <h1>路由區域</h1>
20             <ui-view> </ui-view>
21         </div>            
22     </body>
23 </html>

     以下是改良后的渲染效果,只要點擊            

                   

  •  在本文最后, 演示一下如何在state中加載controller

           controller: 1. 外部文件Controller的名字,注意文件命名時要把controller和前面的單詞區分開,比如“MainController”, 最好前面一個單詞首字母大寫,Controller也是一樣,方便解析

                               2. 直接寫一個函數

                                  

    現在,我們把app.js的代碼再編輯下,如下:

 1 'use strict';
 2 // Define `TrialApp` module
 3 var app = angular.module('TrialApp', ['ui.router']);
 4 // Define routers
 5 app.config(function($stateProvider) {
 6     $stateProvider
 7         .state('C1', {
 8             url:'/C1',
 9             template: '<h4>進入C1狀態</h4>',
10             controller:'C1Controller'
11         })
12         .state('C2', {
13             url: '/C2',
14             templateUrl: 'Htmls/C2.html',
15             controller: function() {
16                 this.test = 'world!';
17             },
18             controllerAs: 'C2Ctrl'
19         })
20         .state('C3', { 
21             url: '/C3',
22             templateProvider: function() {
23                 return '<h4>進入C3狀態</h4><br />' 
24                         + '<p>{{t}}</p>';
25             },
26             controller: function($scope) {
27                 $scope.t = 'C3Controller is on!';
28             }
29         })
30 });
31 app.controller('mainController', function() {
32     return alert('hello!');
33 });
34 app.run(function($state) {
35     $state.go('C1'); 
36 });

另外創建一個js文件“C1Controller”,代碼如下:

1 'use strict';
2 //Define `C1Controller`
3 app.controller('C1Controller', function() {
4     alert('C1Controller is on!');
5 });

C2.html代碼修改如下:

1 <h4>進入狀態C2</h4><br />
2 <p>Hello, {{C2Ctrl.test}}</p>

 下面是整個應用的效果:

                        

  • 上面的代碼使用了上述兩種方法加載了controller。對於第一種方法,記得創建完相應的js外部文件之后,在index.html加上該文件的路徑,不然,編譯器在解析代碼的時候找不到名字所對應的文件會報錯Error: [$controller:ctrlreg],

          這是都因為controller文件沒有被注冊成功,所以在編寫完之后要注意檢查這一點。

  • 還有一點值得注意的是,在狀態C2和C3中,分別都用了內置controller的方法,在方法中創建變量,並在對應頁面中顯示其值。

          在C2中,用了this.test(this指當前對象)聲明並初始化變量,為了能在C2對應頁面中顯示變量值,需要將controller設置別別名,controllerAs: ‘C2Ctrl’,

          然后在對應html模板中用{{C2Ctrl.test}}

          而在C3中,在controller中用$scope創建變量,在對應html模板中用{{t}},這里$scope對應的就是該controller的作用域,所以在與其關聯的html文本中,直接寫出該變量即可。

  • 那這里,有人也許會問,我在這里也寫一個contorllerAs,給controller取個別名,然后再{{controller.變量}}行不行?

         答案是不行(親測有效)。記得AngularJS官網的phonecatApp示例中,曾提到過一句話,如果應用規模大,controller數量多而雜的情況下,在設置controller過程中,盡量避免$scope。

         個人覺得是因為,$scope代表一個controller的作用域,如果有多個controller,那就會有多個$scope,那如果大家都有$scope,那放在一起,誰會清楚這是那個作用域的屬性?所以個人

         覺得controller給controller起個別名是一個比較好的方法,這樣一眼就是識別這是哪個controller,方便代碼后期維護,也方便別人(你的同事們)解讀。

  • 好了,今天主要是對ui-router入門的講解。希望能通過這一簡單的示例,讓大家能對ui-router的一個基本原理有所了解。下一次將會進階地講ui-router的東西,比如多個視圖、路由嵌套及與ngRoute的對比。如果本文有哪些講解得不夠細致或有錯誤的地方,歡迎讀者指正。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM