# 增加路由
> yo angular:route klass/index
```
panjiedeMacBook-Pro:app panjie$ yo angular:route klass/index
invoke angular:controller:/usr/local/lib/node_modules/generator-angular/route/index.js
create app/scripts/controllers/klass/index.js
create test/spec/controllers/klass/index.js
invoke angular:view:/usr/local/lib/node_modules/generator-angular/route/index.js
create app/views/klass/index.html
```
## V層
```
<input type="text" ng-model="name" />
<button type="button" ng-click="query()">確定</button>
<select ng-change="query()" ng-model="pageSize">
<option ng-value="2">2</option>
<option ng-value="3">3</option>
<option ng-value="4">4</option>
</select>
<table class="table">
<tr>
<th>序號</th>
<th>班級名稱</th>
<th>輔導員</th>
<th>操作</th>
</tr>
<tr ng-repeat="(index, klass) in klasses">
<td>{{$index + 1}}</td>
<td>{{klass.name}}</td>
<td>{{klass.teacher.name}}</td>
<td></td>
</tr>
</table>
<nav class="text-center">
<ul class="pagination">
<li class="{{activeClass(1)}}">
<a ng-click="changePage(1)" href="javascript:void(0);">1</a>
</li>
<li class="{{activeClass(2)}}">
<a ng-click="changePage(2)" href="javascript:void(0);">2</a>
</li>
</ul>
</nav>
<div class="debug" ng-show="isDebug">
{{name}}
<br /> {{page}}
<br /> {{pageSize}}
<br /> {{klasses}}
</div>
```
## C層
```
'use strict';
/**
* @ngdoc function
* @name webAppApp.controller:KlassIndexCtrl
* @description
* # KlassIndexCtrl
* Controller of the webAppApp
*/
angular.module('webAppApp')
.controller('KlassIndexCtrl', function ($scope) {
// 初始化
var klasses = [];
$scope.page = 1; // 第幾頁
$scope.pageSize = 2; //每頁大小
$scope.totalCount = 10; // 總條數
$scope.name = ''; // 查詢條件
$scope.isDebug = true; // 開發環境
klasses.push({id:1, name:'一年級一班', teacher: {name: '王五'}});
klasses.push({id:2, name:'一年級二班', teacher: {name: '趙六'}});
klasses.push({id:3, name:'二年級一班', teacher: {name: '孫七'}});
$scope.klasses = klasses;
});
```
## 統一處理配置信息
我們在M層新建一個配置文件,存放項目的一些配置信息。這樣,當項目上線時,只需要更改這一個配置文件就可以了。
比如我們在上面的V層中設置了:如果是開發環境,那么就顯示下面的開發信息,否則就不顯示。
> yo angular:constant config
config.js
```
'use strict';
/**
* @ngdoc service
* @name webAppApp.config
* @description
* # config
* Constant in the webAppApp.
*/
angular.module('webAppApp')
.constant('config', {
isDebug: false, // 開發模式
});
```
## 依賴注入
有了統一的配置文件,現在,我們將配置文件注入至klass/index.js
```
$scope.isDebug = config.isDebug; // 開發模式
```
## 動態處理分頁
我們在V層中,對系統進行分頁,但是靜態分頁。下面,我們更改為動態分頁。
算法: 總頁數 = 總條數 / 每頁大小;
在此,我們使用ng-repeat結合我們自定義的filter來實現此功能。
### 改寫為ng-repeat
V層:
```
<nav class="text-center">
<ul class="pagination">
<li ng-repeat="page in [1,2]" class="{{activeClass(page)}}">
<a ng-click="changePage(page)" href="javascript:void(0);">{{page}}</a>
</li>
</ul>
</nav>
```
在C層中,增加相應的方法:
```
// 為當前頁增加active樣式
var activeClass = function(index) {
if ($scope.page === index) {
return 'active';
} else {
return '';
}
};
// 用戶點擊分頁觸發
var changePage = function (index) {
$scope.page = index;
};
$scope.activeClass = activeClass;
$scope.changePage = changePage;
```
### 增加filter
```
panjiedeMacBook-Pro:WebApp panjie$ yo angular:filter paginationFilter
create app/scripts/filters/paginationfilter.js
create test/spec/filters/paginationfilter.js
```
paginationFilter.js
```
'use strict';
/**
* @ngdoc filter
* @name webAppApp.filter:paginationFilter
* @function
* @description
* # paginationFilter
* Filter in the webAppApp.
*/
angular.module('webAppApp')
.filter('paginationFilter', function() {
return function(items, pageSize, totalCount) {
// 計算共多少頁
var page = totalCount / pageSize;
// 按頁數大小push數組
for (var i = 1; i <= page; i++) {
items.push(i);
}
// 返回包含有分頁的數組
return items;
};
});
```
### 單元測試
```
'use strict';
describe('Filter: paginationFilter', function() {
// load the filter's module
beforeEach(module('webAppApp'));
// initialize a new instance of the filter before each test
var paginationFilter;
beforeEach(inject(function($filter) {
paginationFilter = $filter('paginationFilter');
}));
it('每頁2條,共10條,共5頁', function() {
var items = [];
expect(paginationFilter(items, 2, 10).length).toBe(5);
});
it('每頁1條,共10條,共10頁', function() {
var items = [];
expect(paginationFilter(items, 1, 10).length).toBe(10);
});
it('每頁2條,共11條,共6頁', function() {
var items = [];
expect(paginationFilter(items, 2, 11).length).toBe(6);
});
```
由于前面,我們新C層時,沒有進行單元測試。或是有單元測試已失效。可以將其單元測試的測試部分注釋掉,以免對我們千萬干擾。
測試結果:
```
PhantomJS 2.1.1 (Mac OS X 0.0.0) Filter: paginationFilter 每頁2條,共11條,共6頁 FAILED
Expected 5 to be 6.
test/spec/filters/paginationfilter.js:27:59
loaded@http://localhost:8081/context.js:151:17
```
提示我們最后一條記錄沒有通過,我們期待返回6,但實際上返回了5。這是由于,我們在計算時,沒有進行上取整造成的。
### 修正BUG
增加Math.ceil函數,進行上取整處理。
```
// 計算共多少頁
var page = Math.ceil(totalCount / pageSize);
```
上取整后,我們隨便修改一下單元測試文件并保存,以使單元測試自動執行。測試通過。
## 將分頁過濾器添加到前臺
```
<li ng-repeat="page in [] | paginationFilter:pageSize:totalCount" class="{{activeClass(page)}}">
<a ng-click="changePage(page)" href="javascript:void(0);">{{page}}</a>
</li>
```
加入過濾器后,大體的執行過程是這樣的:
1. 在進行ng-repeat以前,將`[]`和`pageSize`,`totalCount`傳給過濾器.

2. 過濾器進行計算后,將我們計算后的值返回給`ng-repeat`

> 沒錯,過濾器,不但可以按我們的需求進行數據的修改,還可以去除一些我們認為不符合條件的,還可以呢去添加一些我們所需要的數據。
過濾器之所以能夠在ng-repeat中過濾,是由于過濾器的優先級大于ng-repeat。
# 作業
1. 按上述方法,將 系統配置 注入至 教師管理 ,并按是否為開發模式,在前臺顯示測試信息。
2. 將serve.js中的URL前綴`http://127.0.0.1:8080/javaee`放到`config.js`中,并將`config`注入`server`以實現相同的功能。
> git checkout -f step12.1.1
- README
- 第一章:準備
- 第二章:Hello World!
- 第一節:查看工程文件
- 第二節:JDK、JRE與環境變量
- 第三節:index.jsp
- 第三章:Hello Struts
- 第一節:Web.xml
- 第二節:單入口
- 第三節:Hello Struts
- 第四節:觸發C層
- 第四章:建立數據表
- 第一節:建立實體類
- 第二節:測試一
- 第三節:測試二
- 第四節:引入Hibernate
- 第五節:配置Hibernate
- 第六節:建立連接
- 第七節:實體類映射數據表
- 第八節:完善數據表
- 第五章:教師管理
- 第一節:增加數據--add
- 第二節:增加數據--save
- 1 獲取傳入數據數據
- 2 數據寫入測試
- 3 對接C層
- 第三節:數據列表
- 1 獲取數據
- 2 重構代碼
- 3 C層對接--初始化
- 4 C層添加數據
- 5 V層顯示數據
- 6 獲取數據庫中數據
- 7 顯示性別
- 8 分頁
- 9 條件查詢
- 第四節:修改數據
- 1 edit
- 2 update
- 第五節:刪除數據
- 第六節:總結
- 第六章:重構C層
- 第一節:繼承ActionSupport類
- 第二節:數據驗證
- 第七章:前臺分離(前臺)
- 第一節:環境搭建
- 第二節:運行環境
- 第三節:共享開發環境
- 第四節:生產環境
- 第八章:前臺開發(前臺)
- 第一節:本地化
- 第二節:教師列表
- 1 引入M層
- 2 模擬后臺返回數據
- 3 C與M對接
- 4 C與V對接
- 第九章:前后臺對接(前后臺)
- 第一節:后臺輸出json(后臺)
- 第二節:對接前臺(全棧)
- 第二節:對接API(前臺)
- 第二節:跨域請求(后臺)
- 第三節:重構代碼(前臺)
- 第十章:重構后臺M層
- 第一節:數據訪問DAO層
- 第二節:項目整體重構
- 第十一章:用戶登陸(前后臺)
- 第一節:制定規范
- 第二節:定制測試用例
- 第三節:后臺輸入測試代碼(后臺)
- 第四節:postman(后臺)
- 第五節:新建用戶登陸模塊(前臺)
- 第六節:代碼重構(前臺)
- 第十二章:班級管理(前后臺)
- 第一節:班級列表
- 1 原型開發
- 2 制定規范
- 3 后臺對接開發
- 4 前臺對接開發
- 第二節:Add
- 1 原型開發
- 2 制定規范
- 3 后臺對接開發
- 4 前臺對接開發
- 第三節:Save
- 1 制定規范
- 2 后臺對接開發
- 3 前臺對接開發
- 第四節:Edit
- 1 原型開發
- 2 制定規范
- 3 后臺對接開發
- 4 前臺對接開發
- 第五節:Update
- 1 制定規范
- 2 后臺對接開發
- 3 前臺對接開發
- 第六節:Delete
- 1 制定規范
- 2 后臺對接開發
- 3 前臺對接開發
- 第七節:小結
- 第十三章:班級管理(API)
- 第一節:ER圖
- 第二節:create
- 1 實體層
- 2 dao層
- 3 service(server)層
- 4 action層
- 第三節:ManyToOne
- 第四節:Read
- 1 service(server)層
- 2 action層
- 第五節:update
- 1 service(server)層
- 2 action層
- 第六節:update
- 第十四章:重構服務層