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等屬性
- 瞭解完定義狀態的用法,我們可以看一下例項程式碼:
app.config(function($stateProvider) { $stateProvider .state('C1', { url:'/C1', template: '<h1>進入C1狀態</h1>' }) .state('C2', { url: '/C2', templateUrl: 'Htmls/C2.html' }) .state('C3', { url: '/C3', templateProvider: function() { return '<h1>進入C3狀態</h1>'; } }) });
- 上面程式碼中,我們給狀態配置物件分配了三個狀態,“C1”、“C2”和"C3"。當應用程式狀態為以上三個狀態時,url會自動切換到定義的地址,而且也會顯示相應的html模板。其中,有三種顯示html模板的方式
template: 一個html內容字串或一個能返回html字串的函式, 如狀態C1處程式碼;
templateUrl: 一個html模板的路徑字串或者是一個能返回URL路徑字串的函式,如狀態C2處程式碼;
templateProvider:一個能返回URL路徑字串的函式,如狀態C3處程式碼;
- 現在,我們來寫一下index.html和app.js檔案,實現一下ui-router:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>index</title> <link href="css/index.css" rel="stylesheet" /> <script src="js/lib/angular/angular.min.js"></script> <script src="js/lib/angular-ui-router/release/angular-ui-router.min.js"></script> <script src="app.js"></script> </head> <body ng-app="TrialApp" ng-controller="mainController" style="background-color: lightblue;"> <h1>index頁面</h1> <div style="width: 80%; float: right;background-color: #C0C0C0;"> <h1>路由區域</h1> <ui-view> </ui-view> </div> </body> </html>
- 建立一個定義TrialApp模組檔案app.js:
'use strict'; // Define `TrialApp` module var app = angular.module('TrialApp', ['ui.router']); // Define routers app.config(function($stateProvider) { $stateProvider .state('C1', { url:'/C1', template: '<h1>進入C1狀態</h1>' }) .state('C2', { url: '/C2', templateUrl: 'Htmls/C2.html' }) .state('C3', { url: '/C3', templateProvider: function() { return '<h1>進入C3狀態</h1>'; } }) });
- 這時,並不能一進入頁面就能看見路由的效果,需要我們通過寫程式碼來啟用狀態。啟用state有3種方法:
1.呼叫$state.go('stateName');方法;
2. 在html文件中<ui-view>區域之外的地方,新增<a ui-sref='stateName'>stateName</a>連結,等頁面渲染之後可以通過點選該連結進入所選狀態所對應的頁面;
3. 在位址列中輸入state中定義過的url,隨後Enter直接訪問。
- 現在我們來演示一下上述方法中的前面兩種啟用狀態的方法:
方法1: 如果需要在頁面一載入時就要顯示某一狀態,需要在app.js後面加一下程式碼:
app.run(function($state) { $state.go('C1'); });
上述程式碼是在載入該模組的時候呼叫$state.go('C1');,以啟用C1狀態。執行以後就是以下效果:
方法2:在html文件中<ui-view>區域之外的地方,新增<a ui-sref='stateName'>stateName</a>連結,程式碼如下:
<a ui-sref='C1'>C1</a><br /> <a ui-sref='C2'>C2</a><br /> <a ui-sref='C3'>C3</a>
由於上述效果有點醜,我們調整下html程式碼:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>index</title> <link href="css/index.css" rel="stylesheet" /> <script src="js/lib/angular/angular.min.js"></script> <script src="js/lib/angular-ui-router/release/angular-ui-router.min.js"></script> <script src="app.js"></script> </head> <body ng-app="TrialApp" ng-controller="mainController" style="background-color: lavender;"> <h1>index頁面</h1> <div style="width: 20%; float: left;background-color: lightgoldenrodyellow;text-align: center;"> <a ui-sref='C1'>C1</a><br /> <a ui-sref='C2'>C2</a><br /> <a ui-sref='C3'>C3</a> </div> <div style="width: 80%; float: right;background-color: #C0C0C0;"> <h1>路由區域</h1> <ui-view> </ui-view> </div> </body> </html>
以下是改良後的渲染效果,只要點選
- 在本文最後, 演示一下如何在state中載入controller
controller: 1. 外部檔案Controller的名字,注意檔案命名時要把controller和前面的單詞區分開,比如“MainController”, 最好前面一個單詞首字母大寫,Controller也是一樣,方便解析
2. 直接寫一個函式
現在,我們把app.js的程式碼再編輯下,如下:
'use strict'; // Define `TrialApp` module var app = angular.module('TrialApp', ['ui.router']); // Define routers app.config(function($stateProvider) { $stateProvider .state('C1', { url:'/C1', template: '<h4>進入C1狀態</h4>', controller:'C1Controller' }) .state('C2', { url: '/C2', templateUrl: 'Htmls/C2.html', controller: function() { this.test = 'world!'; }, controllerAs: 'C2Ctrl' }) .state('C3', { url: '/C3', templateProvider: function() { return '<h4>進入C3狀態</h4><br />' + '<p>{{t}}</p>'; }, controller: function($scope) { $scope.t = 'C3Controller is on!'; } }) }); app.controller('mainController', function() { return alert('hello!'); }); app.run(function($state) { $state.go('C1'); });
另外建立一個js檔案“C1Controller”,程式碼如下:
'use strict'; //Define `C1Controller` app.controller('C1Controller', function() { alert('C1Controller is on!'); });
C2.html程式碼修改如下:
<h4>進入狀態C2</h4><br />
<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,方便程式碼後期維護,也方便別人(你的同事們)解讀。
- 好了,今天主要是對ui-router入門的講解。希望能通過這一簡單的示例,讓大家能對ui-router的一個基本原理有所瞭解。下一次將會進階地講ui-router的東西,比如多個檢視、路由巢狀及與ngRoute的對比。如果本文有哪些講解得不夠細緻或有錯誤的地方,歡迎讀者指正。
感謝大佬的講解,並附上大佬的部落格頁面。
轉載自:https://www.cnblogs.com/VictorYe/p/7099165.html