Skip to content
This repository has been archived by the owner on Jul 28, 2022. It is now read-only.

feilongDisplay pager ajax

feilong edited this page Oct 19, 2016 · 5 revisions

在web应用中,分页是常用的功能,并且分为:

  1. 普通的跳转分页(参见 跳转分页),
  2. 本文要提到的ajax 分页

下面我们介绍下,如何使用 feilong-taglib jar 来实现ajax 分页的功能

1. 示例实现:

参见地址: https://www.speedo.com.cn/offlineStore/storeList.htm/

当点击页码的时候,显示的数据和页码要局部刷新,而页面不跳转

2. Ajax分页实现步骤

2.1 步骤1 JS发送Ajax分页请求

	function loadPageData(pageNo) {
	    console.clear();
	    var url = _contextPath + "/item/commentAjax/" + itemId + ".json";
	    console.log(url);
	
	    loxia.asyncXhrPost(url, {
	        "pageNo" : pageNo
	    }, {
	        success : function(pagerAndContent) {
	        		console.log(pagerAndContent);
				$("#commentPager").html(pagerAndContent.content);
	
	            //do your logic,maybe use handlebars render result
	        }
	    }, {
	        error : function(data) {
	            console.log(data);
	        }
	    });
	}

2.2 步骤2 Controller接收请求并处理

    @ClientCache(value = TimeInterval.SECONDS_PER_MINUTE * 30) // 30分钟客户端 缓存
    @RequestMapping(value={"/item/commentAjax/{itemId}.json"},method=RequestMethod.POST,headers= HEADER_WITH_AJAX_SPRINGMVC)
    @ResponseBody
    public CommentPagerAndContent doHandler2(@PathVariable("itemId") Long itemId,HttpServletRequest request){
        Pagination<RateCommand> rateCommandPagination = getRateCommandPagination(itemId, request);
        if (Validator.isNullOrEmpty(rateCommandPagination)){
            return null;
        }

        Pager<CommentViewCommand> pager = toCommentViewCommandPager(request, rateCommandPagination);
        //***********************************************************************************
        CommentPagerAndContent commentPagerAndContent = new CommentPagerAndContent();
        commentPagerAndContent.setPager(pager);
        commentPagerAndContent.setContent(getPagerContent(Integer.parseInt("" + pager.getCount()), request));
        commentPagerAndContent.setItemRateFitTypeAndValueMap(commentManager.calcSizeCommentScale(itemId));
        return commentPagerAndContent;
    }

    private Pagination<RateCommand> getRateCommandPagination(Long itemId,HttpServletRequest request){
        Page page = constructPage(request);

        Sort[] sorts = Sort.parse("tpir.create_time desc");
        Pagination<RateCommand> rateCommandPagination = sdkItemManager.findItemRateListByItemId(page, itemId, sorts);

        if (Validator.isNullOrEmpty(rateCommandPagination) || Validator.isNullOrEmpty(rateCommandPagination.getItems())){
            LOGGER.info("when itemId:[{}],rateCommandPagination isNullOrEmpty or isNullOrEmpty(rateCommandPagination.getItems()) ", itemId);
            return null;
        }

        if (LOGGER.isDebugEnabled()){
            LOGGER.debug("rateCommandPagination:{}", JsonUtil.format(rateCommandPagination));
        }
        return rateCommandPagination;
    }

    private Pager<CommentViewCommand> toCommentViewCommandPager(HttpServletRequest request,Pagination<RateCommand> rateCommandPagination){

        List<RateCommand> items = rateCommandPagination.getItems();

        String itemCode = items.get(0).getItemCode();

        //理论上来说,只有 下架或者 上架状态的商品 才会进行load 评论数据
        ResultAndViewCommand buildWithCache = stdItemBuilder.buildWithCache(itemCode);
        StdItemViewCommand stdItemViewCommand = (StdItemViewCommand) buildWithCache.getViewCommand();
        OrderLineSalesPropertyNameAndValueMapResolver orderLineSalesPropertyNameAndValueMapResolver = new OrderLineSalesPropertyNameAndValueMapResolverImpl(
                        sdkOrderLineManager,
                        stdItemViewCommand);
        List<CommentViewCommand> commentViewCommandList = (List<CommentViewCommand>) CollectionUtils
                        .collect(items, new CommentViewCommandTransformer(orderLineSalesPropertyNameAndValueMapResolver));

        Pager<CommentViewCommand> pager = new Pager<CommentViewCommand>(
                        getPageNoParam(request),
                        perPageSize(),
                        Integer.parseInt("" + rateCommandPagination.getCount()));
        pager.setItemList(commentViewCommandList);

        if (LOGGER.isDebugEnabled()){
            LOGGER.debug(JsonUtil.format(pager));
        }
        return pager;
    }

    private String getPagerContent(Integer totalCount,HttpServletRequest request){
        PagerParams pagerParams = new PagerParams(totalCount, PagerType.NO_REDIRECT);

        pagerParams.setVmPath("velocity/pdp-pager-for-comment.vm");//评论的分页模板
        pagerParams.setPageSize(perPageSize());
        pagerParams.setCurrentPageNo(getPageNoParam(request));
        return PagerBuilder.buildPagerContent(pagerParams);
    }

上面方法中,关键参数是 PagerType.NO_REDIRECT,标识渲染出来的html代码不需要跳转

2.3 步骤3 解析Ajax返回结果

拿到Ajax 返回结果后, 你可以使用

   
	$("#commentPager").html(pagerAndContent.content);
	

将分页结果内容渲染到某div 或者p标签容器内

2.4 原理解析

PagerType 参数类型设置为 PagerType.NO_REDIRECT ,解析出来的分页的链接将使用 javascript:void(0); 替代

下面是渲染出来的html

render

2.5 步骤4 点击页码,取到分页码值发送新的Ajax请求

当点击分页码,需要取到分页码的数值,发送新的Ajax请求到controller,可以在上面的原理图中看出,每个非当前页码上的A标签均有一个pageNoValue自定义属性,因此,你可以使用下面的方式取到该值,发送新页码Ajax请求:

	$("#commentPager a:not(.btn-disabled)").live("click", function() {
	    loadPageData($(this).attr("pageNoValue"));
	});
	

3. 关于自定义Ajax velocity/pdp-pager-for-comment.vm 分页模板

	##第页不显示首页和上页
	#if(1 != ${pagerVMParam.currentPageNo})
		<a class="next" pageNoValue="${pagerVMParam.prePageNo}" title="${i18nMap.get('feilong-pager.text.goto.pre')}" href="${pagerVMParam.preUrl}">${i18nMap.get('feilong-pager.text.prev')}</a>
	    ##// 如果导航编号里面没有首页 则添加首页
		##// 导航里面 是否有第一页, 如果从开始1索引 则已经包含的首页包含
		
		#if (${pagerVMParam.startIteratorIndex} != 1)
			<a pageNoValue="1" title="${i18nMap.get('feilong-pager.text.goto.first')}" href="${pagerVMParam.firstUrl}">1</a>
		#end
	#end
	
	##开始迭代索引不等于1,并且开始迭代索引不等于2,显示3点
	#if (${pagerVMParam.startIteratorIndex} != 1 && ${pagerVMParam.startIteratorIndex} != 2)
		<span class="color_666">...</span>
	#end
	
	##循环所有的页码 显示导航编号
	#foreach( ${entry} in ${pagerVMParam.iteratorIndexMap.entrySet()} )
		##当前 直接是数字编号
	    #if(${entry.key}==${pagerVMParam.currentPageNo})
	    	<a class="btn-disabled" href="${entry.value}">${entry.key}</a>
	    #else
			##不是当前页面
			<a pageNoValue="${entry.key}" title="${entry.key}${i18nMap.get('feilong-pager.text.pager')}" href="${entry.value}">${entry.key}</a>
	    #end
	#end
	
	##如果最后个迭代索引不等于总页数,且最后个迭代索引不等于总也是-1,那么 显示3点
	#set($allPageNoTo1=${pagerVMParam.allPageNo} - 1)
	#if (${pagerVMParam.endIteratorIndex} != ${pagerVMParam.allPageNo} && ${pagerVMParam.endIteratorIndex} != $allPageNoTo1)
		<span class="color_666">...</span>
	#end
	
	##最后页不显示下页和末页
	#if(${pagerVMParam.allPageNo}!=${pagerVMParam.currentPageNo})
		## 如果导航编号里面没有尾页 则添加尾页
		##导航里面是否有最后页, 如果结束的位置是allPageNo 则已经包含的尾页
		#if(${pagerVMParam.endIteratorIndex} != ${pagerVMParam.allPageNo})
			##跳转到最后页
			<a pageNoValue="$!{pagerVMParam.allPageNo}" title="${i18nMap.get('feilong-pager.text.goto.last')}" href="${pagerVMParam.lastUrl}">$!{pagerVMParam.allPageNo}</a>
		#end
	
		##跳转到下页
		<a class="next" pageNoValue="${pagerVMParam.nextPageNo}" title="${i18nMap.get('feilong-pager.text.goto.next')}" href="${pagerVMParam.nextUrl}">${i18nMap.get('feilong-pager.text.next')}</a>
	#end