• 基于avalon1.4.x ----分页组件编写


    avalon分页组件 (1.4.x版本)

    随着avalon2的推出,avalon1的官网已经不再维护了,现在似乎是找不到avalon 1.4版本的官方文档了,所以本文章所有的内容均不保证正确性,只能保证在同样的前置条件下可以实现相同的功能,具体代码见github内容。

    本文UI基于bootstrap创建,使用的avalon版本为avalon 1.4.7。具体代码如下:

    template代码为下面代码:

    <style>
        .current {
            background-color: #2d97de !important;
            color: #fff !important;
        }
       </style>
    <div ms-controller="page" ms-widget="pager,testtest,$opts">
        <ul class="pagination" ms-if="pageCount>1">
            <li ms-click="homePage()" ms-class="{{currentPage==1?'disabled':''}}"><a href="##">首页</a></li>
            <li ms-click="lastPage()" ms-class="{{currentPage==1?'disabled':''}}"><a href="##">上一页</a></li>
            <li><a href="##" ms-if="firstDotShow">...</a></li>
            <li ms-repeat="showArr" ms-click="goTomodel(el)"><a href="##" ms-text="el" ms-class="{{el==currentPage?'current':''}}"></a></li>
            <li><a href="##" ms-if="lastDotShow">...</a></li>
            <li ms-click="nextPage()" ms-class="{{currentPage==pageCount?'disabled':''}}"><a href="##">下一页</a></li>
            <li ms-click="endPage()" ms-class="{{currentPage==pageCount?'disabled':''}}"><a href="##">尾页</a></li>
        </ul>
    </div>
    

    如上面代码,其中ms-controller的vmodel名是自定义的,且不能重复。引用分页组件的方法为:ms-widget="pager,testtest,$opts",其中,pager为组件名,testtest为新生成的vmodel名,且不能够与已经存在的vmodel重复,因为实际生成了这些vmodel了(avalon中ms-controller的值是不能重复的)。$opts为传入的参数值,可以传入用户自定义的参数值,如在本例中,自定义的值为:

            $opts: {
                pageCount: 1, 
                cb: avalon.noop
            }
    

    表示传入组件的总页数为1,回调函数为空函数,在初始化(avalon.ready)的时候再书写回调函数。

    组件的书写代码如下:

    //使用avalon自带的amd加载器,加载组件依赖avalon
    define(["avalon"],function (avalon) {
        //组件名为pager,这就是为什么ms-widget里面第一个参数是pager
        avalon.ui["pager"] =function (element, data, vmodels) {
            var innerHTML = element.innerHTML;
            //由于innerHTML要依赖许多widget后来添加的新属性,这时如果被扫描肯定报“不存在”错误
            //因此先将它清空
            avalon.clearHTML(element);
            //重新定义一个vmodel,如果要使用组件内的数据,用‘data.组件名+条件’获取。
            //如下面代码的 data.pagerId即获取组件当前的controller,data.pagerOptions为获取组件的参数,         即html中的$opts
            //如果想要在新建的vmodels里面修改参数值只需要把该参数设为如下形式:
            // var test = data.pagerOptions.test;
            //这样子就可以在html(本文的html表示使用组件的环境)里面修改test值,但本文不建议这么做。
            //建议将这一新建的vmodel设成一个黑盒,让用户无法修改里面的数据,以提高组件的复用性,如果想         要通过html修改分页的内容的话,下面会有介绍。
            var model=avalon.define(data.pagerId,function (vm) {
                //将传过来的参数深拷贝(mix,用法见文档)
                avalon.mix(vm,data.pagerOptions);
                vm.currentPage=1;
                vm.pageArr=[];
                vm.showArr=[];
                vm.lastDis=true;
                vm.nextDis=false;
                vm.firstDotShow=false;
                vm.lastDotShow=false;
                vm.getPages=function () {
                    //使用range创建循环数组
                    model.pageArr=avalon.range(1,this.pageCount+1);
                    model.showPage();
                };
                vm.showPage=function () {
                    var count=this.pageCount;
                    var current=model.currentPage;
                    //分页逻辑判断
                    if (count<6){
                        model.showArr=model.pageArr;
                        model.firstDotShow=false;
                        model.lastDotShow=false;
                    }else if(current<4){
                        model.showArr=avalon.range(1,6);
                        model.firstDotShow=false;
                        model.lastDotShow=true;
                    }else if(current>count-3){
                        model.showArr=avalon.range(count-4,count+1);
                        model.firstDotShow=true;
                        model.lastDotShow=false;
                    }else{
                        model.showArr=avalon.range(current-2,current+3);
                        model.firstDotShow=true;
                        model.lastDotShow=true;
                    }
                    //自定义回调
                    this.cb(current);
                };
                vm.lastPage=function () {
                    if (model.currentPage>1){
                        model.currentPage--;
                    }
                };
                vm.nextPage=function () {
                    if(model.currentPage<model.pageCount){
                        console.log(that)
                        model.currentPage++;
                    }
                };
                vm.homePage=function () {
                    model.currentPage=1;
                };
                vm.endPage=function () {
                    model.currentPage=model.pageCount;
                };
                vm.goToModel=function (index) {
                    model.currentPage=index;
                }
                vm.$watch('currentPage',function () {
                    //监听到当前页发生改变时,重新渲染页面
                    this.showPage();
                });
            });
            model.$init=function() {
                //初始化
                element.innerHTML = innerHTML;
                model.getPages();
                avalon.scan(element, [model].concat(vmodels));
            };
            return model;//必须返回model
        }
        //在default里面可以设置实例化后自定义的数据
        avalon.ui["pager"].defaults = {
            pageCount:1
            //里面定义的内容均可以在实例化后进行修改
        };
        return avalon ;  //必须返回avalon
    })
    

    从上面的代码可以得到,组件书写的大体思路如下:

    1. 引入依赖avalon,然后,命名组件名为 avalon.ui[comomponentName] =function (element, data, vmodels) {}
    2. 将template中的内容缓存到临时变量,然后清空template内的内容。
    3. 新建一个vmodel,形式如下,其中新生成的vmodel为data.pagerId,即pagerId为固定形式(uiName+'Id'),深拷贝传入的参数,然后在进行内部运算:
    var model=avalon.define(data.pagerId,function (vm) {
        avalon.mix(vm,data.pagerOptions);
        ...
    }
    
    1. 对新生成的vmodel使用model.$init进行初始化设置,并在这时候进行扫描,保证新生成的属性能够被扫描到,同时返回model。
    2. 对组件进行初始化设置,使用关键字defaults.

    总结一下大概的思路如下面代码所示:

     define(['avalon'],function(avalon){
        avalon.ui['pager'] =function(element,data,vmodels){
            var innerHTML=element.innerHTML;
            avalon.clearHTML(element);
            var model=avalon.define(data.pagerId,function(vm){
                avalon.mix(vm,data.pagerOptions);
                ...
            })
            model.$init=function(){
                ...
            }
            return model;
        }
        
        avalon.ui['pager'].defaults={
            ...
        };
        
        return avalon;
     })
    

    实例化方法如下:

    1. 在页面中使用上述中的template作为分页内容。
    2. js代码实例如下,引入pager组件,然后在初始化的时候传入需要的回调函数,并给自定义的参数$opts赋值:
    //还是利用avalon自带的amd加载器
     require(["pager"], function () {
        var vm = avalon.define({
            $id: 'page',
            $opts: {
                pageCount: 1, 
                cb: avalon.noop
            }
        });
        avalon.ready(function () {
                $.ajax({
                    url: URL,
                    ...
                    success: function (res) {
                        vm.$opts.pageCount = res.pageCount;
                        vm.$opts.cb = ...
                        };
                        avalon.scan()
                    },
                    error: function (xhr, status, err) {
                        console.log(err);
                    }
                });
            });
    });
    

    目前掌握的avalon1.4版本的组件就是这么写的,应该还是存在诸多问题,希望知晓的大神能够不吝指出。

  • 相关阅读:
    装饰者模式【结构模式】
    代理模式【结构模式】
    原型模式【构建模式】
    建造者模式【构建模式】
    抽象工厂模式【构建模式】
    工厂模式【构建模式】
    单例模式【构建模式】
    设计原则
    Collector 源码分析
    Maven 包命令
  • 原文地址:https://www.cnblogs.com/monkeyleo/p/5997625.html
Copyright © 2020-2023  润新知