stores的数据来源不单单可以从client-side获得(就是从Registry里获得),也可以通过调用远程数据来获得。对于远程数据的加载和处理工作,GXT已经提供了轻巧方便的手段。她支持通过HTTP协议来检索XML或者JSON格式的数据,或者直接通过GWT RPC来检索到objects对象。对于不同的数据源,GXT提供了相应的机制。如果有必要的话,会把原始的数据转换成ModelData并且自动的放入store里。
对于远程数据的处理过程,会涉及到几个components(非可视化组件)。他们各尽其责,协同工作完成远程数据的检索和加工等操作。
这个几个components的相互作用,协同工作图解如下:
DataProxy | 描述 |
HttpProxy | 通过GWT的Requestbuilder传输同一个server的数据,读取XML或JSON格式的数据。 |
MemoryProxy | 简单的通过指定的构造函数传递数据 |
PagingModelMemoryProxy | 类似MemoryProxy,但是支持在从memory中读取数据时分页 |
RpcProxy | 使用GWT RPC来检索数据,允许其过程中通过loader将javabean数据转换 |
ScriptTagProxy | 通过一个URL来检索其返回的数据,其URL可以是别的域名,而不是自己服务器运行的域名。但是只支持JSON |
下面是一组列表,介绍不同类型的具体的DataReader实现类
DataReader | 输入数据类型 | 转换时,使用的工具类 | 输入数据类型 | 何时使用此Reader |
ModelReader | ModelData | 输入的已经是ModelData,不需要何人转换,只要放入到ListLoadResult即可 | ListLoadResult | 当加载的原始数据已经继承BeanModel |
BeanModelReader | JavaBean的集合 | BeanModelFactory | ListLoadResult | 当加载的原始数据是普通的javabean,需要使用他将其转换成BeanModel |
JsonReader | JSON数据 | ModelType定义 | ModelData结果集 | 当原始数据是Json类型时 |
JsonLoadResult Reader |
JSON数据 | ModelType定义 | ListLoadResult | 当原始数据是Json类型时 |
JsonPagingLoadResult Reader |
JSON数据 | ModelType定义 | PagingLoadResult | 当原始数据是Json类型时 |
XmlReader | XML数据 | ModelType定义 | ModelData结果集 | 当原始数据是xml类型时 |
XmlLoadResultReader | XML数据 | ModelType定义 | ListLoadResult | 当原始数据是xml类型时 |
XmlPagingLoadResult Reader |
XML数据 | ModelType定义 | PagingLoadResult | 当原始数据是xml类型时 |
上面的列表大家会注意到“ModelType定义”这句话。ModelType是在Reader在进行转换的时候会用到的类。
拿XML类型的数据来说,其结构比如:
The best book in the world
The worst book in the world
final ModelType modelType = new ModelType();
modelType.setRoot("books");
modelType.setRecordName("book");
modelType.addField("title");
ModelType当然也支持定义Json数据类型的结构。如下的Json数据,ModelType的定义同上
{
"books": [
{
"book": {
"title": "The best book in the world"
},
"book": {
"title": "The worst book in the world"
}
}
]
}
Loader是所有接口根接口,与之对应的BaseLoader是所有抽象类的根抽象类。当然BaseLoader实现了Loader接口。请看下图:
Loader一共就分两类:一个是List一个是Tree。打开源码一看便知之前的关系。
Loaders可以在数据加载的时候,将其排序,可以功过setSortField,setSortDir方法进行设置,当然也可以通过LoadConfig对象来设置。
LoadConfig配置了数据是如何被Loader到store的。Loadconfig接口有一系列的实现类(BaseGroupingLoadConfigBasePagingLoadConfig),看名称就猜到大概意思这里就不详细介绍了。我自己也没怎么研究。。。
package com.danielvaughan.rssreader.client.lists;
import java.util.List;
import com.danielvaughan.rssreader.client.RSSReaderConstants;
import com.danielvaughan.rssreader.client.services.FeedServiceAsync;
import com.danielvaughan.rssreader.shared.model.Feed;
import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelReader;
import com.extjs.gxt.ui.client.data.ListLoadResult;
import com.extjs.gxt.ui.client.data.ListLoader;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.form.ListField;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;
public class FeedList extends LayoutContainer {
public FeedList() {
setLayout(new FitLayout());
}
@Override
protected void onRender(Element parent, int index) {
super.onRender(parent, index);
final ListField feedList = new ListField();
//0:从Registry里获得Service
final FeedServiceAsync feedService = (FeedServiceAsync) Registry
.get(RSSReaderConstants.FEED_SERVICE);
//1:定义proxy在load方法里嗲用Serivce里的方法
RpcProxy> proxy = new RpcProxy>() {
@Override
protected void load(Object loadConfig,
AsyncCallback> callback) {
feedService.loadFeedList(callback);
}
};
//2:定义Reader
BeanModelReader reader = new BeanModelReader();
//3:将proxy和reader传入,定义loader
ListLoader> loader = new BaseListLoader>(
proxy, reader);
//4:传入loader,生成store,此时还没有load数据
ListStore feedStore = new ListStore(loader);
//5:将stroe绑定到data-backed component身上
feedList.setStore(feedStore);
feedList.setDisplayField("title");
//6:真正的load数据,load成功之后,data-backed component会自动的显示出来。
loader.load();
add(feedList);
}
}