`
xiushan
  • 浏览: 30740 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

关于自定义分页的Loop组件:PagedLoop实现

阅读更多

我根据Grid的实现方式,写了一个pagedloop组件,设计了一个LoopDataSource接口作为pagedloop的source,主要是希望从数据库中抓取每页所需的记录,而不是所有记录。 
LoopDataSource.java: 

public interface LoopDataSource extends Iterable<Object>{
	
	int getTotalRowCount();
	
	void prepare(int startIndex, int endIndex, String propertyName);
}

 

public class HibernateLoopDataSource implements LoopDataSource {
	
	private final Session session;

    private final Class<?> entityType;

    private int startIndex;

    private List<Object> preparedResults;

    public HibernateLoopDataSource(Session session, Class<?> entityType){
    	assert session != null;
        assert entityType != null;
        this.session = session;
        this.entityType = entityType;
    }

    public int getTotalRowCount(){
    	Criteria criteria = session.createCriteria(entityType);
    	criteria.setProjection(Projections.rowCount());

        Number result = (Number) criteria.uniqueResult();

        return result.intValue();
    }
    
    @SuppressWarnings("unchecked")
	public void prepare(int startIndex, int endIndex, String propertyName){
    	Criteria crit = session.createCriteria(entityType);

        crit.setFirstResult(startIndex).setMaxResults(endIndex - startIndex + 1);

        if(propertyName!=null){
              crit.addOrder(Order.desc(propertyName));
        }
        
        this.startIndex = startIndex;
        
        preparedResults = crit.list();
    }
    
   
	@Override
	public Iterator<Object> iterator() {
		// TODO Auto-generated method stub
		return preparedResults.iterator();
	}
}

 

public class PagedLoop implements ClientElement {

	 //@Parameter(value = "prop:componentResources.id", defaultPrefix = "literal")
	 //private String clientId;
	 
	 /**
	  * The element to render. If not null, then the loop will render the
	  * indicated element around its body (on each pass through the loop). The
	  * default is derived from the component template.
	  */
	 @Parameter(value = "prop:componentResources.elementName", defaultPrefix = "literal")
	 private String elementName;

	/**
	 * The element to render. If not null, then the loop will render the
	 * indicated element around its body (on each pass through the loop). The
	 * default is derived from the component template.
	 */
	 @Parameter(required = true, principal = true, autoconnect = true)
	 private LoopDataSource source;

	/**
	 * A wrapper around the provided Data Source that caches access to the
	 * availableRows property. This is the source provided to sub-components.
	 */
	private LoopDataSource cachingSource;
	
	/**
	 * Defines where the pager (used to navigate within the "pages" of results)
	 * should be displayed: "top", "bottom", "both" or "none".
	 */
	@Parameter(value = "bottom", defaultPrefix = "literal" )
	private String pagerPosition;
	
	private GridPagerPosition internalPagerPosition;

	/**
	 * The number of rows of data displayed on each page. If there are more rows
	 * than will fit, the Grid will divide up the rows into "pages" and
	 * (normally) provide a pager to allow the user to navigate within the
	 * overall result set.
	 */
	@Parameter("25")
	private int rowsPerPage;
	
	@Persist
	private int currentPage;
	
	/**
	 * The current value, set before the component renders its body.
	 */
	@SuppressWarnings("unused")
	@Parameter
	private Object value;
	
	/**
	 *If true and the Loop is enclosed by a Form, then the normal state saving logic is turned off.
     * Defaults to false, enabling state saving logic within Forms.
	 */
	@SuppressWarnings("unused")
	@Parameter(name = "volatile")
	private boolean volatileState;

	/**
     * The index into the source items.
     */
	@SuppressWarnings("unused")
	@Parameter
	private int index;
	
	/**
	 * Optional primary key converter; if provided and inside a form and not
	 * volatile, then each iterated value is converted and stored into the form.
	 */
	@SuppressWarnings("unused")
	@Parameter
	private ValueEncoder<?> encoder;
	
	@SuppressWarnings("unused")
	@Component(parameters = { "source=dataSource",
			"elementName=prop:elementName", "value=inherit:value",
			"volatile=inherit:volatileState", "encoder=inherit:encoder",
			"index=inherit:index" })
	private Loop loop;
	
	@Component(parameters = { "source=dataSource", "rowsPerPage=rowsPerPage",
	"currentPage=currentPage" })
	private Pager pager;
	
	@SuppressWarnings("unused")
	@Component(parameters = "to=pagerTop")
	private Delegate pagerTop;

	@SuppressWarnings("unused")
	@Component(parameters = "to=pagerBottom")
	private Delegate pagerBottom;
	
	/**
	 * A Block to render instead of the table (and pager, etc.) when the source
	 * is empty. The default is simply the text "There is no data to display".
	 * This parameter is used to customize that message, possibly including
	 * components to allow the user to create new objects.
	 */
	@Parameter(value = "block:empty")
	private Block empty;

	private String assignedClientId;
	
        @Parameter(name="OrderBy", defaultPrefix="literal")
        private String propertyName;
	 /**
     * A version of LoopDataSource that caches the availableRows property. 
     */
    static class CachingDataSource implements LoopDataSource
    {
        private final LoopDataSource delegate;

        private boolean availableRowsCached;

        private int availableRows;

        CachingDataSource(LoopDataSource delegate)
        {
            this.delegate = delegate;
        }

        public int getTotalRowCount()
        {
            if (!availableRowsCached)
            {
                availableRows = delegate.getTotalRowCount();
                availableRowsCached = true;
            }

            return availableRows;
        }

        public void prepare(int startIndex, int endIndex, String propertyName)
        {
            delegate.prepare(startIndex, endIndex, propertyName);
        }

        
		@Override
		public Iterator<Object> iterator() {
			
			return delegate.iterator();
		}
    }

	public String getElementName() {
		return elementName;
	}
	
	public Object getPagerTop() {
		return internalPagerPosition.isMatchTop() ? pager : null;
	}

	public Object getPagerBottom() {
		return internalPagerPosition.isMatchBottom() ? pager : null;
	}

	public int getRowsPerPage() {
		return rowsPerPage;
	}

	public void setRowsPerPage(int rowsPerPage) {
		this.rowsPerPage = rowsPerPage;
	}
	
	public int getCurrentPage() {
		return currentPage;
	}

	public void setCurrentPage(int currentPage) {
		this.currentPage = currentPage;
	}

	void setupDataSource()
    {
        cachingSource = new CachingDataSource(source);

        int availableRows = cachingSource.getTotalRowCount();

        if (availableRows == 0)
            return;

        int maxPage = ((availableRows - 1) / rowsPerPage) + 1;

        // This captures when the number of rows has decreased, typically due to deletions.

        int effectiveCurrentPage = getCurrentPage();

        if (effectiveCurrentPage > maxPage)
            effectiveCurrentPage = maxPage;

        int startIndex = (effectiveCurrentPage - 1) * rowsPerPage;

        int endIndex = Math.min(startIndex + rowsPerPage - 1, availableRows - 1);

        cachingSource.prepare(startIndex, endIndex, propertyName);
    }
	
	Object setupRender() {
		if (currentPage == 0)
			currentPage = 1;
		
		internalPagerPosition = new StringToEnumCoercion<GridPagerPosition>(
                GridPagerPosition.class).coerce(pagerPosition);

		setupDataSource();

        // If there's no rows, display the empty block placeholder.

        return cachingSource.getTotalRowCount() == 0 ? empty : null;

	}

	Object beginRender() {
		// Skip rendering of component (template, body, etc.) when there's
		// nothing to display.
		// The empty placeholder will already have rendered.
		return (cachingSource.getTotalRowCount() != 0);
	}
	
	void onAction(int newPage){
		currentPage = newPage;
	}

	/**
     * Returns a unique id for the element. This value will be unique for any given rendering of a
     * page. This value is intended for use as the id attribute of the client-side element, and will
     * be used with any DHTML/Ajax related JavaScript.
     */
    @Override
	public String getClientId()
    {
        return assignedClientId;
    }
    
    public LoopDataSource getDataSource(){
    	return cachingSource;
    }
    public String getPropertyName(){
           return propertyName;
    }
}

 

@Property
private Blog blog;
@Inject
private Session session;

public LoopDataSource getList(){
	return new HibernateLoopDataSource(session, Blog.class);
}
 
分享到:
评论

相关推荐

    小程序自定义分页选择组件

    小程序自定义选择分页组件. 三个参数 max_page:最大分页数 page:当前选择页 show:是否显示 bind: selectPage 分页选择事件 引入组件即可使用

    java分页标签自定义分页标签自定义分页标签

    自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签自定义分页标签...

    WinForm自定义分页控件

    WinForm自定义分页控件完整实例,导入可用

    分页:高度自定义分页

    2.1.目前网络上很多分页主键,不能进行按钮选择, 2.2.甚至对样式修改的难度也较大, 2.3.使用在开发过程中由于使用到了分页功能,在这里写了一个分页功能。 3.按钮选择 之前的很多按钮是通过参数进行选择,这样不...

    Qt 实现的自定义分页控件

    Qt 实现的自定义分页控件,内部包含:样式文件、用到的资源文件以及源码等。

    自定义分页标签自定义分页标签

    自定义分页标签自定义分页标签自定义分页标签自定义分页标签 多个关键字请用空格分隔,最多填写5个。点击右侧Tag快速添加

    基于vue2和element-ui实现的自定义分页表格组件

    这个资源是一个基于vue2和element-ui实现的自定义分页表格组件,是将element-ui的表格组件和分页组件封装成了一个组件,可以指定接口地址,快速实现分页表格的渲染,减少前端代码的编写。使用的技术:vue2.6.14、...

    mvc自定义分页封装

    LibHelper是一个支持自定义分页的工具类,详细介绍看这里 “MVC实现自定义分页”http://blog.csdn.net/xyj2014/article/details/49761963

    gridview实现自定义分页

    gridview实现自定义分页

    swiper自定义分页器的样式

    本文实例为大家分享了swiper自定义分页器的样式代码,供大家参考,具体内容如下 js主要代码 pagination: { // 自定义分页器的类名----必填项 el: '.custom-pagination', // 是否可点击----必填项 clickable: ...

    android自定义分页控件

    android自定义分页控件,内有详细注释。简洁明了。 使用方便。

    java自定义分页标签

    自定义分页标签3套,淘宝购物分页标签样式,分为多套风格不一的分页标签

    C#自定义分页控件动态绑定

    内容概况:自定义分页控件,实现了对数据的实时绑定,DataGridView等控件实现了完美兼容及绑定,能实时显示当前页码,总页码,页码选中的状态会记录,打比方你选中了第一页,当你切换到下一组页码时,第一页的选中...

    Angular2自定义分页组件

    本篇文章主要介绍了Angular2自定义分页组件的相关知识。具有很好的参考价值。下面跟着小编一起来看下吧

    jsp自定义分页标签

    jsp自定义分页标签,参考http://blog.csdn.net/fastthinking/article/details/12849065

    ASP自定义分页效果

    ASP自定义分页效果ASP自定义分页效果ASP自定义分页效果

    asp.net 自定义分页

    asp.net 自定义分页,内置演示分页SQL数据库。

    自定义分页控件的实例演示WEB版

    纯HTML代码分页 自定义分页控件的实例演示WEB版 可以看源码

    自定义分页标签 Java

    自定义分页标签 自 定 义 分 页 标 签

Global site tag (gtag.js) - Google Analytics