ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 增加路由 > 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`传给过滤器. ![https://box.kancloud.cn/210214eee21229d5763a4882dbecc73d_2328x510.png](https://box.kancloud.cn/210214eee21229d5763a4882dbecc73d_2328x510.png) 2. 过滤器进行计算后,将我们计算后的值返回给`ng-repeat` ![https://box.kancloud.cn/ac90a1496fef78bbd7a91e8077ae2edc_2336x484.png](https://box.kancloud.cn/ac90a1496fef78bbd7a91e8077ae2edc_2336x484.png) > 没错,过滤器,不但可以按我们的需求进行数据的修改,还可以去除一些我们认为不符合条件的,还可以呢去添加一些我们所需要的数据。 过滤器之所以能够在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