GXT之旅:第五章:高级Components(3)——Paging

Paging

Paging是GXT提供的非常有用的功能。顾名思义,就是分页显示数据,而不是一页显示所有的数据。GXT支持远程和本地的分页:远程分页就是真分页,每次server端返回数据都是数据库里分页后的数据;本地的分页就是假分页,数据库一次性load全部数据后,前端再分页内存里面的数据。为了方便起见,仅仅使用假分页,给大家展示一下Paging的功能。害羞

介绍一下分页工作的相关类

PagingLoadResult

分页的数据,其必须被填充到PagingLoadResult。PagingLoadResult是ListLoadResult的扩展接口,提供了额外的功能(TotalLength和Offset),

PagingLoadConfig

PagingLoadConfig封装了请求分页数据的参数,指定了offset,数据返回起始点等。

接下来,我们要在RSSReader项目里,新建一个方法,返回PagingLoadResult<Item>

  • FeedService接口里,定义第二个loadItems方法,

PagingLoadResult<Item> loadItems(String feedUrl, final
PagingLoadConfig config);

  • FeedServiceAsync接口里,定义其回调方法
void loadItems(String feedUrl, PagingLoadConfig config,
AsyncCallback<PagingLoadResult<Item>> callback);
  • FeedServiceImpl里,实现这个抽象方法。
    @Override
    public PagingLoadResult<Item> loadItems(String feedUrl,
            PagingLoadConfig config) {
        List<Item> items = loadItems(feedUrl);
        return getPagingLoadResult(items, config);
    }
  • getPagingLoadResult的方法实现如下:
private PagingLoadResult<Item> getPagingLoadResult(List<Item> items,
			PagingLoadConfig config) {
		//定义pageItems,存储Item,作为返回的数据源
		List<Item> pageItems = new ArrayList<Item>();
		//通过PagingLoadConfig,获得相关参数(offset)
		int offset = config.getOffset();
		//获得全部数据大小
		int limit = items.size();
		//根据offset获得limit
		if (config.getLimit() > 0) {
			limit = Math.min(offset + config.getLimit(), limit);
		}
		//定义好边界之后,开始读取数据
		for (int i = offset; i < limit; i++) {
			pageItems.add(items.get(i));
		}
		//通过pageItems,转化成BasePagingLoadResult,同时赋值上offset和totalLength
		return new BasePagingLoadResult<Item>(pageItems, offset, items.size());

	}

PagingModelMemoryProxy

对于返回分页的数据的方法的代理proxy需要使用PagingModelMemoryProxy,针对于PagingModelMemoryProxy的loader是PagingLoader

PagingLoader

PagingLoader的构造函数里,参数指明了类型是PagingModelMemoryProxy,PagingLoader会通过PagingModelMemoryProxy,load分页的数据集到store里。

PagingLoader<PagingLoadResult<ModelData>> loader = new BasePagingLoader<PagingLoadResult<ModelData>>(proxy);
对于load数据的时候,需要指定offset和pageSize

loader.load(0, 4);//public void load(int offset, int pageSize);
对于其过程使用的store是ListStore,因为数据本身来说,就是一般的list数据集,分页的操作只是从大的list数据集里面获取部分数据集。

PagingToolBar

PagingToolBar extends ToolBar,预定义了相关的分页功能。


对于PagingToolBar来说,他数据源所绑定的是PagingLoader,大致代码如下:

toolBar.bind(loader);
add(toolBar);
接下来,我们要在RSSReader项目里实现上面提到的所有概念。

  • 新建ItemPagingGrid类,整个代码内容如下:
package com.danielvaughan.rssreader.client.grids;

import java.util.ArrayList;
import java.util.List;

import com.danielvaughan.rssreader.client.RSSReaderConstants;
import com.danielvaughan.rssreader.client.services.FeedServiceAsync;
import com.danielvaughan.rssreader.shared.model.Item;
import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.data.BasePagingLoader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.extjs.gxt.ui.client.data.PagingLoader;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.toolbar.PagingToolBar;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class ItemPagingGrid extends LayoutContainer {

	private static final int PAGE_SIZE = 2;

	public ItemPagingGrid() {
		setLayout(new FitLayout());
	}

	@Override
	protected void onRender(Element parent, int index) {
		super.onRender(parent, index);
		// ColumnModel
		final List<ColumnConfig> columns = new ArrayList<ColumnConfig>();
		GridCellRenderer<ModelData> itemsRenderer = new GridCellRenderer<ModelData>() {
			@Override
			public Object render(ModelData model, String property,
					ColumnData config, int rowIndex, int colIndex,
					ListStore<ModelData> store, Grid<ModelData> grid) {
				String title = model.get("title");
				String description = model.get("description");
				return "<b>" + title + "</b><br/>" + description;
			}
		};
		ColumnConfig column = new ColumnConfig();
		column.setId("items");
		column.setRenderer(itemsRenderer);
		column.setHeader("Items");
		columns.add(column);
		final ColumnModel columnModel = new ColumnModel(columns);

		// Proxy:
		final String TEST_DATA_FILE = "http://127.0.0.1:8888/rss2sample.xml";
		final FeedServiceAsync feedService = Registry
				.get(RSSReaderConstants.FEED_SERVICE);
		RpcProxy<PagingLoadResult<Item>> proxy = new RpcProxy<PagingLoadResult<Item>>() {
			@Override
			protected void load(Object loadConfig,// loadConfig是GXT内部自动传入的
					AsyncCallback<PagingLoadResult<Item>> callback) {
				feedService.loadItems(TEST_DATA_FILE,
						(PagingLoadConfig) loadConfig, callback);
			}
		};
		// Loader:根据proxy,生成loader,因为返回的类型正好是PagingLoadResult,不需要数据转换
		PagingLoader<PagingLoadResult<Item>> loader = new BasePagingLoader<PagingLoadResult<Item>>(
				proxy);
		// Store:
		ListStore<ModelData> itemStore = new ListStore<ModelData>(loader);
		// PagingToolBar:定义的时候需要传入分页大小
		final PagingToolBar toolBar = new PagingToolBar(PAGE_SIZE);
		toolBar.bind(loader);
		// Grid:定义的时候,需要传入store和columnModel
		Grid<ModelData> grid = new Grid<ModelData>(itemStore, columnModel);
		grid.setBorders(true);
		grid.setAutoExpandColumn("items");
		loader.load();//此时的load应用了默认的PagingLoadConfig
                // Grid不直接加入到LayoutContainer,而是Grid添加到ContentPanel,ContentPanel添加到LayoutContainer
		ContentPanel panel = new ContentPanel();
		panel.setLayout(new FitLayout());
		panel.add(grid);
		panel.setHeaderVisible(false);
		panel.setBottomComponent(toolBar);
		add(panel);
	}
}
  • 最后把ItemPagingGrid添加到RssMainPanel里,显示出来。注释掉之前的components
package com.danielvaughan.rssreader.client.components;

import com.danielvaughan.rssreader.client.grids.ItemPagingGrid;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;

public class RssMainPanel extends ContentPanel {
	public RssMainPanel() {
		setHeading("Main");
		setLayout(new FitLayout());
//		add(new ItemGrid());
//		add(new ItemCategoryGrid());
		add(new ItemPagingGrid());
	}
}
  • 运行结果如下


  • 如果想让Grid在加载数据的时候直接到第二页。可以使用:loader.load(2, PAGE_SIZE);
  • 只要绑定了(toolBar.bind(loader);)loader之后,其翻页操作不需要我们实现,PagingToolBar内部已经实现好了。


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值