加载中…
个人资料
神灯欧巴
神灯欧巴
  • 博客等级:
  • 博客积分:0
  • 博客访问:110,547
  • 关注人气:3
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
谁看过这篇博文
加载中…
正文 字体大小:

Ext Store详解

(2013-09-17 10:20:08)
标签:

extstore详解

extstore

it

在使用Ext的Grid、ComboBox或DataView时,经常要用到Store,下面将详细分析Store结构。

1.1 Store的结构

    无论是JsonStore、XmlStore、还是ArrayStore,它们的结构与Store都是一样的。不同之处在于它们的Reader不同,ArrayStore已经自动配置其Reader为ArrayReader。同理,JsonStore的Reader为JsonReader,XmlStore的Reader为XmlReader,而Store则需要自己配置Reader。这说明了Store无论读取的数据是数组、JSON对象或XML数据,最终都会转成Store本身的结构,然后提供给界面控件使用。这样的好处就是界面控件不需要为处理不同的数据格式定义不同的处理方式,或者根据不同数据格式做不同的数据格式的界面控件。因而,界面控件的显示问题,譬如没有数据显示、显示格式错误等,与用户返回的数据格式没有任何关系,只与Store中的数据有关系,调试界面控件的显示问题,首先要检查的就是Store的问题,譬如Store中是否有数据、其数据是否正确,等等。

Store主要由data、fields和reader三个部分组成:

* data 部分由Record对象组成数组构成,负责提供数据并记录数据处理信息。

* fields 部分记录Store中数据的字段构成以及如何与原始数据对应的方式。

* reader 部分记录原始数据信息。

 

1.2 Ext.data.Field

Field对象只有几个配置属性,没有方法和时间。其配置属性说明如下:

* allowBlank:是否允许为空值。默认值为true,表示允许为空值。该属性一般在增加一个Record时,校验字段值时使用。

* convert:在将Reader提供的数据转换到Store的Record时会执行该函数。该函数一般在原始数据不是界面控件的显示数据并且需要做一些处理时使用。其使用方法:

复制代码

//convert函数,将firstname与lastname合成后再显示
function fullName(v,record){
return record.name.last + ',' + record.name.first;
};
//如果city不是空值,则结合state一起返回
function location(v,record){
return !record.city ? '' : (record.city + ', ' + record.state);
};

var myRecord = Ext.data.Record.create([
{ name: 'fullname', convert: fullName },
{ name: 'firstname', mapping: 'name.first' },
{ name: 'lastname', mapping: 'name.last' },
{ name: 'city', defaultValue: 'homeless' },
'state',
{ name: 'location', convert: location }
]);

var store = new Ext.data.Store({
reader: new Ext.data.JsonReader({ idProperty: 'key',root: 'rows', totalProperty: 'total' }),
myRecord
});

var myData = [
{ key:1, name: { first: 'Fat', last: 'Albert' } //no city },
{ key:2, name: { first: 'Barney', last: 'Rubble' }, city: 'Bedrock', state: 'Stoneridge' },
{ key:3, name: { first: 'Cliff', last: 'Claven' }, city: 'Boston', state: 'MA' }
];
复制代码

 

一些 实用功能,下面是用法:

* dateFormat:日期格式。

* defaultValue:字段的默认值。当将Reader中原始数据转换成Store的Record时,找不到对应的数据,则使用该值代替。默认值是空字符串。

* mapping:将Reader中的字段映射到Record的字段中,如果Reader中的字段与Record的字段名称相同,可以不设置该属性。

* name:字段的名称。

* storDir:排序方式。值“ASC”表示升序,“DESC”表示降序。默认值是“ASC”。

* type:字段的数据类型。它包含以下数据类型:auto(默认,不会进行数据类型转换)、string、int、float、boolean、date。 

 

1.3 Ext.data.Record 

Record是Store最小的数据单元,它除了记录Store的一行数据信息,还记录了这些数据的状态,并可修改这些状态。其属性和方法如下:

* data:存储了该记录的数据信息。

* dirty:只读属性,表示该记录是否被编辑过。

* fields:记录的字段信息。

* id:当前记录的唯一标记。

* modified:当记录的某个数据被修改后,会在这里保存数据的原始值。

* phantom:当该值为false时,表示服务器端数据库内没有该条数据。

* store:记录所在的store。

* beginEdit:开始编辑记录,其使用方法如下:


record.beginEdit();

* cancelEdit:取消当前记录的修改,其使用方法如下:


record.cancelEdit();

* commit:确认更新数据。一般情况是使用Store的commitChanges方法,其使用方法如下:


record.commit();
record.commit(true); //更新数据但不触发Store的change事件

* copy:复制一个记录。其使用方法如下:


record.copy();        //自动产生一个id
record.copy("id1"); //使用id1作为新记录的id

* create:构建一个记录结构。该方法通常用于为Store增加一条新记录前构造一个记录结构,然后再创建新记录,并添加到Store。其使用方法如下:

复制代码

var TopicRecord = Ext.data.Record.create([
{ name: 'title' },
{ name: 'author',allowBlank: false }
]);
var myNewRerord = new TopicRecord(
{ title: '测试',author: '张三' }
);
myStore.add(myNewRecord);
复制代码

* endEdit:结束编辑。如果有数据被修改,Store的update事件将会被触发,其使用方法参考beginEdit方法。

* get:获取某个字段的值。其使用方法如下:


record.get('company');   //获取company的值

* getChanges:获取被修改的字段。其使用方法如下:


var rec = record.getChanges();   //获取company的值

* isModified:判断某个字段是否已被修改。其使用方法如下:


//判断字段company是否已被修改
if(record.isModified('company'){
//处理过程
}

* isValid:检验Record是否有效,主要是检验设置了Ext.data.Field.allowBlank为true的字段。其使用方法:


if(record.isValid()){
//处理过程
}

* markDirty:标记记录已被修改。其使用方法:


record.markDirty();

* reject:取消记录的修改,回复原值。一般情况是使用Store的rejectChanges方法。其使用方法:


record.reject();
record.reject(true); //更新数据但不触发Store的change事件

* set:设置某个字段的值。其使用方法:


var rec = myStore.getAt(1);  //getAt(n),n表示行的索引值。getAt表示获取行
rec.set('name', '张三');
rec.commit();

 

1.4 ArrayReader、JsonReader和XmlReader

Reader的作用是将源数据转换成Record对象。Store一般使用数组、JSON或XML等3种格式的数据,因而对应建立ArrayReader、JsonReader和XmlReader三个Reader。

因为Reader的作用是进行数据转换,所以定义一个Reader必须包含源数据的格式、Record的格式和两种格式之间的数据如何对应这三个部分。明白这一点,对Reader的定义和使用就简单多了。下面介绍这三种Reader的使用方法。

 

1.4.1 JsonReader

JsonReader的数据定义只要提供root参数即可,它会根据root参数提供的属性名称去获取数据源中的数据。totalProperty参数和idProperty参数都是可选的,totalProperty参数定义的是数据源中保存数据总数的属性名称,idProperty参数定义的是数据源中可作为记录唯一标记的字段名称,如果没有设置,Store会自动产生这个唯一标记。字段映射需要在Record中定义。通过下面的例子来了解一下具体定义方式:

复制代码

var reader = new Ext.data.JsonReader(
{
totalProperty: 'results',
root: 'rows',
idProperty: 'id'
},
[
{ name: 'id',type: 'int'}, //因为Record中该字段名称与数据源同名,所以不用设置mapping参数
{ name: 'username',mapping: 'name' } //映射数据源的name字段到Record的username字段
]
);
//以下返回的数据格式
{
results: 20, //记录总数
rows: [ //数据
{ id: 1, name: '张三' },
{ id: 2, name: '李四' }
...
]
}
复制代码

从代码中可以看到:JsonReader的第一个参数是数据源的定义,主要包含totalProperty、root和idProperty三个参数;第二个参数则是Record对象的定义。如果Record对象的字段名称与数据源的字段名称相同,则不需要定义mapping参数。

 

1.4.2 ArrayReader

ArrayReader是从JsonReader扩展出来的,因为数组其实是JSON的一种简化形式,数组中的索引就相当于JSON格式中的属性名称。通过下面的例子来了解一下具体的定义方式:

复制代码

var reader = new Ext.data.ArrayReader(
{
idIndex: 0
},
[
{ name: 'id',type: 'int',mapping: 0 },
{ name: 'username', mapping: 1 }
]
);
复制代码

从代码中可以看到:在数据源定义部分,idIndex参数代替了JsonReader的idProperty参数,而且其值为数组的索引值;在Record定义部分,mapping定义也由数组的索引值代替了字段名称。如果Record是数组按顺序读取的,也可以不设置mapping.

 

1.4.4 XmlReader

虽然XmlReader不是从JsonReader扩展的,但是其定义方式与JsonReader类似。不同的地方是,使用record参数代替了JsonReader的root参数,id参数代替idProperty参数了。通过下面的例子来了解一下具体的定义方式:

复制代码

var reader = new Ext.data.XmlReader(
{
totalProperty: 'results',
record: 'row',
id: 'id'
},
[
{ name: 'id',type: 'int' }, //因为Record中该字段名称与数据源同名,所以不用设置mapping参数
{ name: 'username',mapping: 'name' } //映射数据源的name字段到Record的username字段
]
);
//以下返回的数据格式


20

1
张三


2
李四

...
复制代码

从代码中可以看到,它的定义与JsonReader的定义没有太大区别,要注意的是数据源的数据格式。

 

1.5 Store的加载数据 

Store加载数据时有一下4种方式

* 在定义Store时,配置autoload参数,这样在Store创建时会自动调用load方法加载数据,其使用方法:

复制代码

var store = new Ext.data.ArrayStore({
autoload: true,
fields: [
{ name: 'company' },
{ name: 'price',type: 'float' },
{ name: 'change',type: 'float' },
{ name: 'pctChange',type: 'float' },
{ name: 'lastChange',type: 'date',dateFormat: 'n/j h:ia' }
]
});

//在autoload中配置提交参数
var store = new Ext.data.ArrayStore({
autoload: { page: 1 },
fields: [
{ name: 'company' },
{ name: 'price',type: 'float' },
{ name: 'change',type: 'float' },
{ name: 'pctChange',type: 'float' },
{ name: 'lastChange',type: 'date',dateFormat: 'n/j h:ia' }
]
});
复制代码

在第二段代码中可以看到,在autoload中定义了一个对象“{page:1}”,该对象会在调用load方法时作为参数传递给load方法。

 

* 在创建Store后,执行load方法。该方法一般用于加载远程数据,其使用方法:

复制代码

var store = new Ext.data.ArrayStore({
fields: [
{ name: 'company' },
{ name: 'price',type: 'float' },
{ name: 'change',type: 'float' },
{ name: 'pctChange',type: 'float' },
{ name: 'lastChange',type: 'date',dateFormat: 'n/j h:ia' }
]
});
store.load();

//带提交参数、回调函数以及追加数据
store.load({
params: { page: 1 },
callback: function(r,opts,success){ //处理过程 },
scope: this,
add: true
});
复制代码

在代码中,回调函数是在Store的load事件执行后才执行的,参数r表示返回的记录集,opts表示调用load方法时的配置参数对象,success表示数据加载是否成功,参数add的作用是指示加载数据后不清空原有的数据,将新数据追加到原有数据里。

 

* 在创建Store后,使用loadData方法加载数据,该方法一般用于加载本地数据,其使用方法:


store.loadData(datas);
//追加方式
store.loadData(datas,true)

 

* 需要刷新数据,可以使用reload方法,其使用方法参考load方法。

在加载数据时,如果要修改提交参数,可使用baseParams属性设置,其使用方法如下:


store.baseParams.page=1;
store.load();

也可以使用setBaseParam方法,其使用方法如下:


store.setBaseParam('page',1);
store.load();

当然,也可以直接在load方法里当参数传递,其使用方法请看前面的load方法介绍。

 

1.6 Store的数据操作

1.6.1 添加数据

要给Store添加数据,可以使用insert方法、add方法、addSorted方法或loadData方法。insert方法将在指定位置开始插入记录,一次可以插入多条记录;add方法则直接增加一条或多条记录;addSorted方法则在排序后的位置插入记录,该方法一次只能插入一条记录。如果要使用loadData方法添加记录,则需要指定第2个参数为true,不然会清空原有数据再追加数据。下面是它们的使用方法:

复制代码

//添加单个记录
var data = { id: 1001,name: '张三' };
var p = new store.recordType(data,data.id);
store.insert(2,p); //在第一条记录后插入
store.add(p);
store.addSorted(p);
store.loadData(p,true);

//添加多个记录
var data1 = { id:1001,name: '张三' };
var p1 = new store.recordType(data1,data1.id);
var data2 = { id:1002,name: '李四' };
var p2 = new store.recordType(data2,data2.id);
store.insert(0,[p1,p2]);
store.add([p1,p2]);
store.loadData([p1,p2], true);
复制代码

 

1.6.2 删除数据

在Store中删除数据有remove、removeAll和removeAt这3种方法。它们的使用方法如下:


store.remove(rec);  //rec为一个记录
store.removeAll(); //删除所有记录
store.removeAt(10); //10为索引值,

从上面代码中可以看到:remove方法需要知道具体的记录才允许删除;removeAll删除全部记录,并触发clear事件;removeAt方法则删除指定位置的记录。

 

1.6.3 搜索、定位和统计

Store提供了以下搜索和定位记录的方法:

* each:枚举所有记录,当枚举函数返回false时,终止枚举操作。其使用方法:


store.each(function(rec){
//处理过程
});

* filter:根据指定属性过滤记录。其使用方法:


//过滤掉不是name不包含“张”的记录
store.filter('name','张',true,false);

代码中的过滤规则可使用字符串,也可以使用正则表达式。第3个参数如果为false,则表示只匹配开始位置,为true则表示匹配任何位置;第4个参数如果为false,则表示不区分大小写,为true则表示要匹配大小写。

* filterBy:通过一个函数过滤记录。该函数会枚举每一个记录,然后根据函数返回值判断记录是否被过滤。如果函数返回true,则包含该记录,如果返回false,则过滤掉该记录。其使用方法:

复制代码

//返回id为单数的记录
store.filterBy(function(rec,id){
if(id%2 == 0){
return true;
}
else {
return false;
}
});
复制代码

* isFiltered:判断Store当前是否处于过滤状态。如果是,返回true;否则,返回false。其使用方法:


if(store.isFiltered()){
store.clearFilter();
}

* clearFilter:将Store恢复到没有进行过滤的状态,其使用方法可参考isFiltered中的代码。

* find:根据指定属性查找匹配的记录,并返回匹配的第一个记录的索引值。如果没有找到匹配的记录,则返回-1。其使用方法如下:


var index = store.filter('name','张',2,true,false);

与filter方法一样,搜索值可以是字符串,也可以是正则表达式。第3个参数为搜索开始位置,默认值是0。第4个参数如果为false,则表示只匹配开始位置,为true则表示匹配任何位置。第5个参数如果为false,表示不区分大小写,如果为true则表示要区分大小写。

* findBy:通过一个函数查找匹配的记录并返回匹配的第一个记录的索引值。该函数会从指定的开始位置枚举每一个记录,然后根据返回值判断记录是否匹配。如果函数返回true,则表示已经找不到匹配记录,枚举操作结束并返回匹配记录的索引值。如果没有找到匹配的记录,方法返回值为-1。其使用方法如下:

复制代码

store.findBy(function(rec,id){
if(id%2 == 0){
return true;
}
else{
return false;
}
}, 2);
复制代码

在代码中,第2个参数“2”表示查找的开始位置。

* findExact:与find方法作用一样,只是没有匹配位置和区分大小写参数。其使用方法可参考find方法。

* getAt:根据索引值获取一个记录,其使用方法:


//获得第2条记录
var rec = store.getAt(2);

* getById:根据记录id返回记录,其使用方法:


//获得id为2的记录
var rec = store.getById(2);

* getCount:返回Store的记录总数。如果没有采用分页方式,则其返回结果与getTotalCount方法一样。如果采用了分页方式,则getCount返回的是Store的记录总数,getTotalCount返回的才是数据库的记录总数,不过前提是要在Reader定义中包含有记录总数的属性。其使用方法:


var count = store.getCount();

* getTotalCount:返回数据库的记录总数,不过前提是Reader必须包含记录总数的属性。其使用方法请参考getCount方法。

* getModifiedRecords:获取执行commit后被修改的记录。要注意的是,返回的记录不包括被删除的记录。其使用:

* getRange:返回指定范围内的记录。其使用方法:


//返回所有记录
var recs = store.getRange();
//返回第2条到第10条之间的记录
var recs = store.getRange(2,10);

* indexOf:返回记录的索引值。如果记录在Store中不存在,则返回-1。其使用方法:


var index = store.inexOf(rec);

* indexOfId:根据记录id返回记录的索引值。如果记录id在Store中不存在,则返回-1。其使用方法:


var index = store.indexOfId(2);  //返回id为2的记录索引值

* query:获取符合指定条件的记录。其返回值为Ext.MixedCollectionxt对象。其使用方法可参考filter方法。

* queryBy:通过一个函数获取指定条件的记录。该函数会枚举每一个记录,然后根据函数返回值判断记录是否被录取。如果函数返回true,则包含该记录,如果返回false,则不选取该记录。其使用方法参考filterBy方法。

* sum:合计指定范围内指定字段的值。其使用方法:


//计算total字段从第2个记录到第10个记录的和 
var total = store.sum('total',2,10);

 

1.6.4 更新数据

当使用Grid时我们会发现,某个数据被修改后,会在其单元格左上角显示一个红色标记,表示该数据被修改过,而包含该数据的记录的dirty属性将被标记为true,说明该记录处于已被更改状态。

如果这时需要取消所有记录的更改,可使用Store的rejectChanges方法,其使用方法:


store.rejectChanges();

如果想确认更改,可使用commitChanges方法或save方法。

commitChanges方法的使用如下:


store.commitChanges();

commitChanges方法会触发Store的update事件。

save方法的使用如下:


store.save();

save方法与commitChanges方法不同的地方是会将更新发送到服务器端。如果配置了Ext.data.Api.actions对象,则根据该定义提交数据。如果没有定义,则使用Store定义的url属性提交数据。

commitChanges方法和rejectChanges方法经常用于Grid中的Checkbox修改。譬如:用户单击Checkbox后,会触发Store的update事件,在update事件里,我们使用Ajax将更新提交到服务器端以更改记录。然后在Ajax的回调函数中,如果服务器端返回的信息表示更新成功,就是用commitChanges方法更新Store;如果不成功,则使用rejectChanges方法取消更改,使客户端的数据与服务器端保持一致,也避免了在Grid单元格中左上角显示数据更改信息,具体使用方法如下:

复制代码

var store = new Ext.data.Store({
url: 'test.ashx',
reader: new Ext.data.JsonReader({
totalProperty: 'results',
root: 'rows',
id: 'id'
},
[
{ name: 'id',type: 'int' },
{ name: 'title' },
{ name: 'ontop',type: 'bool' },
{ name: 'posttime',type: 'date',dateFormat: 'Y-m-d H:i:s' }
]),
remoteSort: true,
listeners: {
update: function(store,rec,op){
//判断是否有记录被编辑
if(op == Ext.data.Record.EDIT){
Ext.Ajax.request({
params: { field: 'ontop',id: rec.data.id },
url: 'action.ashx?act=check',
scripts: true,
success: function(response,options){
var msg = response.responseText;
var obj = Ext.decode(msg);
if(obj){
if(obj.success){
//服务器端更新成功更新数据
app.store.commitChanges();
return;
}
else{
//服务器端更新取消修改
app.store.rejectChanges();
}
if(msg != ''){
Ext.Msg.alert("信息",msg);
}
}
},
failure: function(response,options){
//传输数据失败,取消修改
app.store.rejectChanges();
Ext.Msg.alter("错误","改变文章状态失败!出错信息:" + response.responseText);
}
});
}
}
}
}); //store
复制代码

 

1.6.5 排序

Store的排序分远程排序和本地排序两种方式。如果是远程排序,需要在定义Store是设置remoteSort属性,其使用方法:

复制代码

var store = new Ext.data.Store({
remoteSort: true,
reader: new Ext.data.JsonReader(
{
idProperty: 'key',
root: 'daRoot',
totalProperty: 'total'
},
record //recordType
)
});
复制代码

实行远程排序时,每当顺序改变时,例如单击Grid的列标题,会向服务器提交sort和dir两个排序参数。其中:sort参数表示排序的字段名称,要注意的是,这是Store中定义的字段名称,不是数据库中的字段名称;而dir参数表示排序顺序,字符串“ASC”表示顺序排序,字符串“DESC”表示降序排序,要注意,字符串中的字母必须全部为大写字母。

在本地对记录进行排序,可使用sort方法,其使用方法:


store.sort('name','ASC');

代码表示根据字段“name”对记录进行排序。如果要执行降序排序,则将“ASC”修改为“DESC”。要注意,“ASC”与“DESC”所有字母必须为大写字母。

如果想获取当前排序状态,可使用getSortState方法,其使用方法:


var sortState = store.getSortState();

该方法将返回一个JSON数据,其结构如下:


{
field: '当前排序的字段名称', //比如name或id
direction: '当前的排序顺序' //值为ASC或DESC
}

如果想设置每次调用load方法后默认的排序方式,可以使用setDefaultSort方法,其使用方法:


store.setDefaultSort('name','DESC');

该段代码表示在每次调用load方法之后,默认的排序字段是name,排序顺序为降序。如果要升序排序,请将“DESC”修改为“ASC”,所有字母都必须为大写字母。

在本地排序中,Ext 3.0还是没有将字符串排序使用localeCompare方法进行排序,所以在对中文排序还是存在问题,因而需要重载一下Store的sortData方法,具体如下:

复制代码

if(Ext.data.Store){
Ext.apply(Ext.data.Store.prototype,{
sortData: function(f,direction){
direction = direction || 'ASC';
var st = this.fields.get(f).sortType;
var fn = function(r1,r2){
var v1 = st(r1.data[f]);
var v2 = st(r2.data[f]);
if(typeof(v1) == "string")
return v1.localeCompare(v2);
else
return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
}
};
this.data.sort(direction, fn);
if(this.snapshot && this.snapshot != this.data){
this.snapshot.sort(direction, fn);
}
});
}
复制代码

代码基本是按Ext的源代码修改过来的,修改的地方是先判断v1的值是否是字符串,如果是,则使用localeCompare方法比较数据,否则按照原来的方式比较。可以将该段代码放在本地化文件(ext-lang-zh_CN.js)中,这样就不需要根据页面情况加入这段代码来。

 

1.7 DataProxy

因为Store的数据来源不同,因而需要通过不同的DataProxy来获取数据并提供给Reader。在Ext 3.0中包含了MemoryProxyHttpProxyScriptTagProxyDirectProxy等4种DataProxy。

MemoryProxy主要用来获取本地数据,使用方法如下:

复制代码

var myData =
[
['3m Co',71.72,0.02,0.03,'9/1 12:00am'],
['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am']
]
var store = new Ext.data.Store({
proxy: new Ext.data.MemoryProxy(myData),
reader: new Ext.data.ArrayReader({ },
[
{ name: 'company' },
{ name: 'price',type: 'float' },
{ name: 'change',type: 'float' },
{ name: 'pctChange',type: 'float' },
{ name: 'lastChange',type: 'date',dateFormat: 'n/j h:ia' }
]
)
});
复制代码

 

HttpProxy是在同域的服务器中获取数据,使用方法如下:

复制代码

var store = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({ url: 'text.ashx' }),
reader: new Ext.data.ArrayReader({ },
[
{ name: 'company' },
{ name: 'price',type: 'float' },
{ name: 'change',type: 'float' },
{ name: 'pctChange',type: 'float' },
{ name: 'lastChange',type: 'date',dateFormat: 'n/j h:ia' }
]
)
});
复制代码

 

在Store中,如果设置了url参数但没有设置proxy参数,则默认使用HttpProxy获取数据

ScriptTagProxy用于跨域的服务器中获取数据其使用可参考HttpProxy的使用方法,它们之间的不同之处在于url的地址,ScriptTagProxy的地址是与页面处于不同域的,而HttpProxy则是在相同域的。

DirctProxy则与Ext.Direct配合使用。其使用方法:

复制代码

var store = new Ext.data.Store({
proxy: new Ext.data.DirectProxy({ directFn: Apps.test.getdate }),
reader: new Ext.data.ArrayReader({ },
[
{ name: 'company' },
{ name: 'price',type: 'float' },
{ name: 'change',type: 'float' },
{ name: 'pctChange',type: 'float' },
{ name: 'lastChange',type: 'date',dateFormat: 'n/j h:ia' }
]
)
});
复制代码


1.8 DataWriter

DataWriter是Ext3.0新增的对象,它的作用是方便在Store和服务器端之间处理记录的添加、修改和删除等操作。通过DataWriter,Store可自动管理记录的CRUD操作的Ajax请求。DataWriter包含JsonWriter和XmlWriter两个扩展,与DataReader一样,JsonWriter和XmlWriter主要是处理的数据格式不同。

使用DataWriter很简单,如下代码:

复制代码

var writer = new Ext.data.JsonWriter({
encode: true,
writerAllFields: true
});
var store = new Ext.data.Store({
...,
writer: writer
});
复制代码

代码中,encode参数是JsonWriter的特有参数,它的默认值是true。如果使用DirectProxy,那么要设置它为false,因为Ext.JsonProvider会使用自己的编码方式处理。如果在使用HttpProxy时,该值设置为false,则HttpProxy会使用Ext.Ajax.request的jsonData设置参数代替params参数。

writerAllFields参数的作用是,如果设置为true,则DataWriter将返回被编辑记录的所有字段,如果设置为false,则只返回被编辑记录修改过的字段,默认值是false。

 

1.9 Ext.data.Api

Ext.data.Api对象也是Ext3.0新增的对象,其作用是管理包括DataProxy的API在内的数据API。可以在API中定义CRUD的create、read、update和destory操作以及相对应的RESTful的HTTP提交方法。使用请看如下:

复制代码

var proxy = new Ext.data.HttpProxy(
...
api: {
create: 'user_action.ashx?act=add',
read: 'user_action.ashx?act=list',
update: 'user_action.ashx?act=update',
destory: 'user_action.ashx?act=del'
}
);

var proxy = new Ext.data.DirectProxy(
...
api: {
create: App.User.Add,
read: App.User.List,
update: App.User.Update,
destory: App.User.Del
}
);
复制代码

从以上代码可看出,如果使用HttpProxy,则设置对应的url即可,如果使用DirectProxy则设置对应的方法。

 

Store总结:

    掌握了Store,对使用Grid、ComboBox和Chart等界面控件就不会有太大的困难。Ext其中的一个设计思路就是数据与界面控件分离,而Store就是管理数据的控件,基本上Grid、ComboBox和Chart的管理数据都在Store中进行的。因而,如果发现不是显示错误,那么基本问题都在Store上,而不是界面控件本身。

0

阅读 评论 收藏 转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有