Ajax方式分页加载列表实现

Posted 凉城

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ajax方式分页加载列表实现相关的知识,希望对你有一定的参考价值。

在前面:

  最近需要用到这个功能,所以这几天一直在研究这个,目前大致功能已实现,后续需要完善,但需要的功能点已完成,记录下;

1、分页功能引入bootstrap的分页插件:

        <script type="text/javascript" src="3rd/jquery/jquery.js"></script>
        <script type="text/javascript" src="3rd/bootstrap/js/bootstrap.min.js"></script>
        <script type="text/javascript" src="3rd/bootstrap/js/bootstrap-paginator.min.js"></script>

2、Ajax没有使用jquery的,而是找了一个方便调试的代码,主要看重支持跨域:

技术分享图片
(function(window,undefined) {
    function ajax(options) {

        //编码数据
        function setData() {
            //设置对象的遍码
            function setObjData(data, parentName) {
                function encodeData(name, value, parentName) {
                    var items = [];
                    name = parentName === undefined ? name : parentName + "[" + name + "]";
                    if (typeof value === "object" && value !== null) {
                        items = items.concat(setObjData(value, name));
                    } else {
                        name = encodeURIComponent(name);
                        value = encodeURIComponent(value);
                        items.push(name + "=" + value);
                    }
                    return items;
                }
                var arr = [],value;
                if (Object.prototype.toString.call(data) == ‘[object Array]‘) {
                    for (var i = 0, len = data.length; i < len; i++) {
                        value = data[i];
                        arr = arr.concat(encodeData( typeof value == "object"?i:"", value, parentName));
                    }
                } else if (Object.prototype.toString.call(data) == ‘[object Object]‘) {
                    for (var key in data) {
                        value = data[key];
                        arr = arr.concat(encodeData(key, value, parentName));
                    }
                }
                return arr;
            };
            //设置字符串的遍码,字符串的格式为:a=1&b=2;
            function setStrData(data) {
                var arr = data.split("&");
                for (var i = 0, len = arr.length; i < len; i++) {
                    name = encodeURIComponent(arr[i].split("=")[0]);
                    value = encodeURIComponent(arr[i].split("=")[1]);
                    arr[i] = name + "=" + value;
                }
                return arr;
            }

            if (data) {
                if (typeof data === "string") {
                    data = setStrData(data);
                } else if (typeof data === "object") {
                    data = setObjData(data);
                }
                data = data.join("&").replace("/%20/g", "+");
                //若是使用get方法或JSONP,则手动添加到URL中
                if (type === "get" || dataType === "jsonp") {
                    url += url.indexOf("?") > -1 ? (url.indexOf("=") > -1 ? "&" + data : data) : "?" + data;
                }
            }
        }
        // JSONP
        function createJsonp() {
            var script = document.createElement("script"),
                timeName = new Date().getTime() + Math.round(Math.random() * 1000),
                callback = "JSONP_" + timeName;

            window[callback] = function(data) {
                clearTimeout(timeout_flag);
                document.body.removeChild(script);
                success(data);
            }
            script.src = url + (url.indexOf("?") > -1 ? "&" : "?") + "callback=" + callback;
            script.type = "text/javascript";
            document.body.appendChild(script);
            setTime(callback, script);
        }
        //设置请求超时
        function setTime(callback, script) {
            if (timeOut !== undefined) {
                timeout_flag = setTimeout(function() {
                    if (dataType === "jsonp") {
                        delete window[callback];
                        document.body.removeChild(script);

                    } else {
                        timeout_bool = true;
                        xhr && xhr.abort();
                    }
                    console.log("timeout");

                }, timeOut);
            }
        }

        // XHR
        function createXHR() {
            //由于IE6的XMLHttpRequest对象是通过MSXML库中的一个ActiveX对象实现的。
            //所以创建XHR对象,需要在这里做兼容处理。
            function getXHR() {
                if (window.XMLHttpRequest) {
                    return new XMLHttpRequest();
                } else {
                    //遍历IE中不同版本的ActiveX对象
                    var versions = ["Microsoft", "msxm3", "msxml2", "msxml1"];
                    for (var i = 0; i < versions.length; i++) {
                        try {
                            var version = versions[i] + ".XMLHTTP";
                            return new ActiveXObject(version);
                        } catch (e) {}
                    }
                }
            }
            //创建对象。
            xhr = getXHR();
            xhr.open(type, url, async);
            //设置请求头
            if (type === "post" && !contentType) {
                //若是post提交,则设置content-Type 为application/x-www-four-urlencoded
                xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
            } else if (contentType) {
                xhr.setRequestHeader("Content-Type", contentType);
            }
            //添加监听
            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4) {
                    if (timeOut !== undefined) {
                        //由于执行abort()方法后,有可能触发onreadystatechange事件,
                        //所以设置一个timeout_bool标识,来忽略中止触发的事件。
                        if (timeout_bool) {
                            return;
                        }
                        clearTimeout(timeout_flag);
                    }
                    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {

                        success(xhr.responseText);
                    } else {
                        error(xhr.status, xhr.statusText);
                    }
                }
            };
            //发送请求
            xhr.send(type === "get" ? null : data);
            setTime(); //请求超时
        }


        var url = options.url || "", //请求的链接
            type = (options.type || "get").toLowerCase(), //请求的方法,默认为get
            data = options.data || null, //请求的数据
            contentType = options.contentType || "", //请求头
            dataType = options.dataType || "", //请求的类型
            async = options.async === undefined ? true : options.async, //是否异步,默认为true.
            timeOut = options.timeOut, //超时时间。 
            before = options.before || function() {}, //发送之前执行的函数
            error = options.error || function() {}, //错误执行的函数
            success = options.success || function() {}; //请求成功的回调函数
        var timeout_bool = false, //是否请求超时
            timeout_flag = null, //超时标识
            xhr = null; //xhr对角
        setData();
        before();
        if (dataType === "jsonp") {
            createJsonp();
        } else {
            createXHR();
        }
    }
    window.ajax = ajax;
  })(window);
MyAjax.js

3、主要使用方法:

var options = {
    bootstrapMajorVersion: 3,
    currentPage: 1, //当前页
    numberOfPages: 5, //显示的页数
    totalPages: 20, //总页数
    itemTexts: function(type, page, current) {
        switch(type) {
            case "first":
                return "首页";
            case "prev":
                return "上一页";
            case "next":
                return "下一页";
            case "last":
                return "末页";
            case "page":
                return page;
        }
    },
    onPageClicked: function(e, originalEvent, type, page) {
        console.log(‘ni dian le ‘+page);
        var data = {pageNo: page,pageSize: 10};
        searchModule.query(data);
        
    }
};

var searchModule = {
    query: function(data) {
        console.log(‘你点了query‘);
        console.log(‘查询条件:‘+JSON.stringify(data))
        ajax({
            type: "post",
            url: "http://10.7.6.7:8880/ms-mcms/cms/asset/search_jsonp.do",
            dataType: "jsonp",
            data: data,
            timeOut: 15000,
            before: function() {
                console.log("before");
                 $(‘#pagination‘).bootstrapPaginator(options);
            },
            success: function(response) {
            //    console.log(response);
                var items = response.articles;
                var html = ‘‘;
                for(index in items){
                    var item = items[index];
                //    console.log(item)
                    html+=‘<li class="row no-margin ng-scope"  onclick="‘+searchModule.click(item)+‘"                                    role="button" tabindex="0"><div class="pull-left item-left">                                        <img class="search-thumb ng-scope" style="background: #202334 url(‘+item.artFrame+‘) no-repeat center;background-size: contain;">                                    </div><div class="item-intro"><div class="row no-margin item-top">                                            <div class="col-md-12 title-box ng-binding">‘+item.basicTitle+‘</div></div>                                        <div class="row no-margin-right item-bottom">                                            <div class="col-md-3 no-padding icon-gray">                                                <i class="glyphicon glyphicon-user "></i>                                                <span class="ng-binding">‘+item.articleAuthor+‘</span>                                            </div></div></div>                                    <div class="pull-right item-right ng-scope" >                                        <div class="ng-binding">                                            <i class="glyphicon glyphicon-facetime-video"></i>‘
                                            +item.dateline+‘</div><div style="margin-top:25px;" class="ng-binding">                                            <i class="fa fa-clock-o"></i>‘+item.dateline+‘</div></div></li>‘;
                }
                $(".topicList").html(html);                
            },
            error: function() {
                console.log("error");
            }
        });
    },
    click: function(item) {
        console.log(‘你点了click‘);
    },
    moreCtrl: function() {
        if($(‘.more‘).hasClass(‘isShow‘)) {
            $(‘.more‘).removeClass(‘isShow‘);
            $(‘#arrowsmall‘).removeClass(‘fa-sort-desc‘);
            $(‘#arrowsmall‘).addClass(‘fa-sort-asc‘);
        } else {
            $(‘.more‘).addClass(‘isShow‘);
            $(‘#arrowsmall‘).removeClass(‘fa-sort-asc‘);
            $(‘#arrowsmall‘).addClass(‘fa-sort-desc‘);
        }
    },
    sortFunc: function(type) {
        if(type == 0) {
            $(‘.sort ul li:first‘).addClass(‘active‘)
            $(‘.sort ul li:last‘).removeClass(‘active‘)
        } else {
            $(‘.sort ul li:last‘).addClass(‘active‘)
            $(‘.sort ul li:first‘).removeClass(‘active‘)
        }
    },
};
$(document).ready(function() {
    var data = {pageNo: 1,pageSize: 10};
    searchModule.query(data);
});

   查询所有--》初始化分页插件--》分页功能实现;

4.后台代码:

  由于jsonp请求只支持get请求,所以在原方法的基础上包一层,开放给jsonp方式访问,并保留原方法;

技术分享图片
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;


@RestController
@RequestMapping("/asset")
public class AssetRS {

    public static final Logger logger = LoggerFactory.getLogger(AssetRS.class);
    

    private String tableName;
    
    private Set<String> columnIds;
    
    @Autowired
    private ISearchAssetBiz searchAssetBiz; 
    
    @ResponseBody
    @RequestMapping(value = "/search",method={RequestMethod.POST,RequestMethod.GET})
    public SearchAssetInfo seachAsset(HttpServletRequest request, @RequestBody SearchPageInfo page){
        int pageSize = page.getPageSize();
        int pageNo = page.getPageNo();
        
        //聚类查询字段
        String fieldGroup = "";
        StringBuffer groups = new StringBuffer("");
        List<String> fields = page.getFields();
        if(fields != null){
            for (String field : fields) {
                groups.append(",").append(field);
            }
            fieldGroup = groups.substring(1);
        }
        
        
        List<String> ids = new ArrayList<>();
        ids.addAll(columnIds);
        int appId = page.getAppId()==null?1:Integer.valueOf(page.getAppId());
        
        int count = searchAssetBiz.getSearchAssetCount(tableName,page.getWhereMap(),appId,ids);
        //分页信息
        SearchPageInfo searchPage = new SearchPageInfo();
        searchPage.setCount(count);
        searchPage.setPageNo(pageNo);
        searchPage.setPageSize(pageSize);
        
        List<MdiyAttrInfo> list = searchAssetBiz.getSearchGroup(tableName, page.getWhereMap(), appId, ids,
                StringUtils.hasText(fieldGroup) ? fieldGroup : null);
        for (MdiyAttrInfo mdiyAttrInfo : list) {
            mdiyAttrInfo.getCategory(); //去重
        }
        
        List<MdiyAttrInfo>  assets = searchAssetBiz.querySearchList(tableName, page.getWhereMap(), appId, ids, pageNo, pageSize, page.getSortMap());
        
        SearchAssetInfo searchAssetInfo = new SearchAssetInfo();
        searchAssetInfo.setArticles(assets);
        searchAssetInfo.setPage(searchPage);
        
        return searchAssetInfo;
    }
    
    @ResponseBody
    @RequestMapping(value = "/search_jsonp",method={RequestMethod.GET})
    public void seachAssetJsonp(HttpServletRequest request,
            HttpServletResponse response,
            @RequestParam(required=false) int pageNo,
            @RequestParam(required=false) int pageSize,
            @RequestParam(required=false) String basictitle,
            @RequestParam(required=false) String Category,
            @RequestParam(required=false) String tag,
            @RequestParam(required=false) String startDate,
            @RequestParam(required=false) String endDate,
            @RequestParam(required=false) String sortField,
            @RequestParam(required=false) String sort){
        
        SearchPageInfo page = new SearchPageInfo();
        page.setPageNo(pageNo);
        page.setPageSize(pageSize);
        Map<String,String> whereMap = new HashMap<>();
        if(StringUtils.hasText(basictitle)){
            whereMap.put("basictitle", basictitle);
            page.setWhereMap(whereMap);
        }
        
        Map<String, String> sortMap = new HashMap<>();
        if(StringUtils.hasText(sortField)){
            sortMap.put(sortField, sort);
            page.setSortMap(sortMap);
        }
        List<String> list = new ArrayList<>();
        list.add("Category");
        list.add("Tags");
        page.setFields(list);
        String callback = (String)request.getParameter("callback");
        SearchAssetInfo info  = seachAsset(request, page);
        String retStr = callback + "(" + JSONObject.toJSONString(info)+")"; 
        try {
            response.getWriter().print(retStr);
        } catch (IOException e) {
            e.printStackTrace();
        }  
    }
    
    
}
View Code

需要注意下,jsonp请求的返回值格式,直接返回json时,前台会报错的;

    String retStr = callback + "(" + JSONObject.toJSONString(info)+")"; 
        try {
            response.getWriter().print(retStr);
        } catch (IOException e) {
            e.printStackTrace();
        }  

目前的功能还不完善,后续更新吧!

 

以上是关于Ajax方式分页加载列表实现的主要内容,如果未能解决你的问题,请参考以下文章

如何使 Codeigniter 中的分页类与 AJAX 一起工作?

Ajax实现无刷新分页

关于分页

Grails App中的双重分页问题

为Primefaces数据列表实现LazyModel时发生异常

Ajax实现phpcms列表分页效果