zoukankan      html  css  js  c++  java
  • Angular简易分页设计(二):封装成指令

    (首先声明本文来自博客园本人原创,转载请说明出处。欢迎关注:http://www.cnblogs.com/mazhaokeng/)

      之前我们讲过,Angular分页代码确实不难实现,但是由于在多个路由页码上使用到了分页,要一版一版地进行复制粘贴确实麻烦。倘若代码需要修改,那就满世界乱跑一处处修改。

      幸好我们有Angular directive(自定义指令)!Angularjs中内置了很多指令,常用的如ng-repeat、ng-class等等,我们也可以自己定义指令,而且在项目中是非常普遍的。具体是啥这里不多说明,推荐一篇文章 https://github.com/zhengweikeng/blog/issues/6 ,上面说的非常清楚。

      

      下面我们详细说说directive的封装。首先我们需要把html做成语义化标签,并把我们需要的变量暴露出来:

     <pagination page="page" max-page="maxPage" ng-click="pageTo()"></pagination>

      我们需要当前页和最大页数。pageTo()是父控制器绑定的函数,用于执行其余代码,不属于分页指令内部函数。然后我们就对directive的各个属性进行设置

    app.directive('pagination', function() {
    return {     
        //
    html
            template:
                '<div class="pagination">' +
                    '<ul class="pager">' +
                        '<li><a href="javascript:void(0)" ng-click="pageGo(1)">首页</a></li>' +
                        '<li><a href="javascript:void(0)" ng-click="pagePre()">上一页</a></li>' +
                    '</ul>' +
                    '<ul>' +
                        '<li ng-repeat="num in pageShowList" ng-class="{active: clickPage == num}">' +
                        '<a href="javascript:void(0)" ng-click="pageGo(num)">{{num}}</a>' +
                        '</li>' +
                    '</ul>' +
                    '<ul class="pager">' +
                        '<li><a href="javascript:void(0)" ng-click="pageNext()">下一页</a></li>' +
                        '<li><a href="javascript:void(0)" ng-click="pageGo(maxPage)">尾页:{{maxPage}}</a></li>' +
                    '</ul>' +
                '</div>',
            //替换
            replace: true,

      首先,html标签名字pagination必须要和js代码一致,而返回的属性template是我们的html代码,需要用字符串的方式拼接起来,replace属性为true,表示代码运行时需要把标签替换成template内的html代码。这样需要用到分页的页码只要引入pagination标签就可以了。

      然后是我们的js代码。由于各个功能函数基本是与父控制器隔离的(模块化),我们需要把代码写在link函数内而不是controller内。controller函数一般用于指令之间可复用代码的编写。详细分页功能实现的代码在前一篇文章中有说明,这里不多说。我们就说说为什么需要对最大页数maxPage进行监听。

                /*  监听最大页数,如果页数变化,重新生成页数数组
                * */
                var watch = $scope.$watch('maxPage', function (newValue, oldValue, scope) {
                    pageList = [];
                    for (var i = 1; i <= newValue; i++) {   //一个个压入页码
                        pageList.push(i);
                    }
                    resetPageOrder($scope.page);
                });

      一开始设计时,我希望能够调用一个函数来对页码数量和页码数组进行初始化,因为在进行数据表搜索时,后台返回不同的表格,那么总页数也要跟着变化,所以初始化总页数和其数组是需要多次执行的。但是directive并没有能够把一个函数直接向父控制器暴露的方式,要强行暴露的话只能把函数封装服务。这样父控制器代码就会混乱了,一方面我需要指令的变量,另一方面又要注入此指令定义的服务,耦合度令人发指。

      我也试过把函数当成变量向外暴露,但是这个方式在本地测试时没问题,在测试服务器上就各种错误。明显这种非官方的小聪明是不能被Angular.js接受的。

      指令内部的变量对外暴露是最简单的,那么只要能让变量触发函数就没问题了。还好我们有Angular提供的$watch服务,只要设置总页数maxPage一旦变化,那么页码数组也重新生成不就得了吗!这样整个指令只需要把当前页page和最大页数maxPage对外暴露就行了,代码的耦合度回到了我们的预期。

      最后我们设置这两个变量的作用域,增加属性scope。

            //作用域
            scope:{
                page: '=',  //等号是双向绑定
                maxPage: '@'  
            },

      scope默认是false,表示一切变量对外暴露。html代码中的属性max-page中的值就与指令中的maxPage绑定了,注意html属性不支持驼峰法命名,所以用“-”分割单词。这里说明下:

    (1)使用@符号进行单向绑定,类似于将父作用域中的变量拷贝一份到指令的独立作用域中。

    (2)使用=符号表示变量是双向绑定的,page是向父作用域暴露的所以不使用@。

      具体项目我放在了Github上: https://github.com/makeng/Angular-pagination-/tree/master,欢迎大家指教。

  • 相关阅读:
    $(window).scrollTop()与$(dom).offset().top
    组织结构图
    杀人游戏
    猜数字游戏
    变量
    2018 -11-23 快捷键
    iOS开发—c语言 ATM取款机(全)2018-11-15
    iOS开发—c语言 ATM取款机(一)
    ios开发学习c语言第一天 2018-11-13
    iOS 面试题
  • 原文地址:https://www.cnblogs.com/mazhaokeng/p/6795576.html
Copyright © 2011-2022 走看看