日期:2014-05-16  浏览次数:20477 次

extJs 2.1学习笔记(Ext.data.Store篇)

? Ext.data.Store,这个东西是JavaScript版的DataTable啊。貌似其他Ajax框架都没有这个玩意啊。可见啦,Ext是真的打算把b/s开发重新变成c/s开发啊。哈哈哈。便宜我等了。待某细研之。
  Store类提供对记录集(Record)的包装,通过前面的研究可知,DataProxy取数据(url或数组或xml或json),DataReader用于从不规范的数据取出并格式化指定结构的记录集。记录的结构由Record.create创建。

  DataProxy通过对Connection的调用取得数据(Response)后,在回调中调用DataReader的read函数,从而把response中的数据解析成记录集,这个记录集将再以回调参数的形式传出来,store实现这个回调,并把里面的Recodrd[]取出来,放到 data这个成员中。store.data是一个MixedCollection对象,MixedCollection作什么用的前面也讲过,它本质就是一个容器,ExtJs确实很好,连容器类都写了。

  有了store.data,数据进了这儿,就好办了,store调用MixedCollection的功能,实现了一些通用的函数,如取指定成员、查询、遍历、事务等等,这些都不足道。什么提交修改、取消修改的功能却是根源于Record。Record类自身就封装了这个功能,Store中只是再次封装罢了,这个原理也很简单。看代码即知。

  上面讲的是通用原理,是大概,下面拣紧要的代码说一下。

  它定义了构造函数,继承自Ext.Observable。第一行代码就是个重点:

  this.data = new Ext.util.MixedCollection(false);

  这是定义data,所有记录都将保存在它里面。

??? this.baseParams = {};
??? // private
??? this.paramNames = {
??????? "start" : "start",
??????? "limit" : "limit",
??????? "sort" : "sort",
??????? "dir" : "dir"
??? };

  baseParams将在调用HttpProxy时用到,它将作为params附加到url末尾。这个东西没有悬念。至于 paramsNames用于保存参数名,start、limit应当用于分页,sort、dir用于排序,不过,我看了通篇的代码,发现,Store本身不提供任何其他分页、排序功能的实现,还是得依靠服务器端的。只不过,这儿提供一种统一的方式罢了。

??? if(config && config.data){
??????? this.inlineData = config.data;
??????? delete config.data;
??? }
  意思是说,如果创建store时,设了config,且config.data存在,那么,将直接从config.data中loadData。构造函数后面一点就有。inlineData这个属性没活多久就被delete了。

??? if(this.url && !this.proxy){
??????? this.proxy = new Ext.data.HttpProxy({url: this.url});
??? }

??? if(this.reader){ // reader passed
??????? if(!this.recordType){
??????????? this.recordType = this.reader.recordType;
??????? }
??????? if(this.reader.onMetaChange){
??????????? this.reader.onMetaChange = this.onMetaChange.createDelegate(this);
??????? }
??? }

??? if(this.recordType){
??????? this.fields = this.recordType.prototype.fields;
??? }

  就是根据config中的情况,创建成员:proxy,reader,recordType,onMetaChange。这了这四个,就好方便在下面定义的load中加载数据并完全记录集的封装。说出来一文不值。

  this.modified = [];

  这个东西用于保存那些有修改过的记录的旧值。之所以能取消修改,正是源于此啊。

  关于addEvents那个语句,就没必要讲了,大伙都懂。

??? if(this.proxy){
??????? this.relayEvents(this.proxy,? ["loadexception"]);
??? }

??? this.sortToggle = {};
 if(this.sortInfo){
  this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction);
 }

??? Ext.data.Store.superclass.constructor.call(this);

??? if(this.storeId || this.id){
??????? Ext.StoreMgr.register(this);
??? }
??? if(this.inlineData){
??????? this.loadData(this.inlineData);
??????? delete this.inlineData;
??? }else if(this.autoLoad){
??????? this.load.defer(10, this, [
??????????? typeof this.autoLoad == 'object' ?
??????????????? this.autoLoad : undefined]);
??? }

  第一个语句中主要就是一个relayEvents,意为延迟事件,这个延迟不是时间延迟哦。它是将当前对像的某些事件处理函数作为另一个对象的处理函数,同者共享,事实上,它的作用就是利用另一对象的事件来触发本对象的事件,从而引发事件处理函数的执行(说得太拗口了吧)。

  那个inlineData上面讲了的,现在应验了,不多讲。从这儿可以看出,如果已从config中传过来数据,那么以直接传的数据为准,如果没有直接传数据,而是通过url,且autoLoad为true,这时就在构造函数中加载数据且完全数据的封装。

  重点代码至此讲了一半,另一半就是load、loadRecords了。