嘿,别看关键就在这儿,事实上,它的代码很少的哦。加上注释才219行。研究研究。
有个事要说一下:DataProxy的子类呢,都有一个load来加载数据,DataReader的子类呢,都有一个read来读取数据。
而Ext.data.JsonReader有两个关键函数:read、readRecords。好了。来研究一下。
Ext.data.JsonReader = function(meta, recordType){
meta = meta || {};
Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
};
这是构造函数。简单。meta是数据格式定义,recordType是记录类型。其中recordType可以是一个定义记录的数组,也可以不传,而把记录的各个字段的定义放到meta中的fields字段中。且看它对父类构造函数的调用:
Ext.data.DataReader = function(meta, recordType){
this.meta = meta;
this.recordType = Ext.isArray(recordType) ?
Ext.data.Record.create(recordType) : recordType;
};
Ext.data.DataReader.prototype = { };
这下全明白了吧。recordType可以是记录类型,可以是字段定义数组,还可以不传。
所以,构造函数就是定义两个属性:meta、recordType。这两东西后面有用。
这个meta、recordType组成如何?这个必须说明,不然,这个类也就没法用了。
meta:
totalProperty json数据中,保存总记录数的属性
successProperty json数据中,保存是否返回成功的属性名
root json数据中,保存记录集的属性的属性名
id json数据中,记录中主键所对应的列的属性名
recordType:
这个东西,事实上要去看Ext.data.Record的create函数的文档,我且把它翻译一下,如下:
create( [Array o] ) : function
创建包含指定字段结构的继承自Ext.data.Record的类。静态方法。
参数:
o : Array
一个定义记录结构的字段信息数组。每个数组元素包含name,其他可选的有:mapping、type。通过它们,可以让Ext.data.Reader从一个数据对象中获取各字段的值。每个字段定义对象都可能包含如下属性:
name : String
在记录中标志一个字段的名字。它通常用于引用指定字段,例如,在定义Ext.grid.ColumnModel的dataIndex属性时,要传过去的。
mapping : String
当在Ext.data.Reader中创建记录时,如何将json对象中指定属性值映射到此字段。
type : String
字段的类型,可能值为:
auto(默认值,没有任何转化)、string、int、float、boolean、date
sortType : Mixed
Ext.data.SortTypes中的一个成员。
sortDir : String
排序方式,"ASC"或者"DESC"。
convert : Function
如果要对这个字段的值进行一些物殊处理,这时需要一个能定制的回调,用它来手工处理值。它的参数如下:
v : Mixed
通过mapping映射找到的值。已从json中取出来的。
rec : Mixed
在json中的,对应于此记录的json对象。
dateFormat : String
用于Date.parseDate函数的格式化字符串。
defaultValue : Mixed
当字段值在原数据中不存在时所取的默认值,默认为空字符串。
用法:
var TopicRecord = Ext.data.Record.create([
{name: 'title', mapping: 'topic_title'},
{name: 'author', mapping: 'username'},
{name: 'totalPosts', mapping: 'topic_replies', type: 'int'},
{name: 'lastPost', mapping: 'post_time', type: 'date'},
{name: 'lastPoster', mapping: 'user2'},
{name: 'excerpt', mapping: 'post_text'}
]);
var myNewRecord = new TopicRecord({
title: 'Do my job please',
author: 'noobie',
totalPosts: 1,
lastPost: new Date(),
lastPoster: 'Animal',
excerpt: 'No way dude!'
});
myStore.add(myNewRecord);
不过,JsonReader有一些细节问题,还要细究。待某家一一道来。
构造函数已讲,下面依代码顺序讲解了。
read : function(response){
var json = response.responseText;
var o = eval("("+json+")");
if(!o) {
throw {message: "JsonReader.read: Json object not found"};
}
return this.readRecords(o);
},
这个是整个JsonReader的关键所在了。君可找到Ext.data.HttpProxy中的loadResponse函数,里面有这么一行代码:
result = o.reader.read(response);
可见,是proxy里面调用reader.read方法才得以取出结果集的。这是要表明:read乃JsonReader三军中军之所在。 read又调用readRecords,read把json字符串转化为对象然后交给readRecords。这个本无不妥,但是,asp.net中,它的结果有点曲折,结果是放在o.d中,而不能直接从o中取得。所以,事实上应当这么写:this.readRecords(o.d)。 这就成了。继续往下面看:
onMetaChange : function(meta, recordType, o){
}
这个函数说是要由store实现的,现在不知道它的用处。还往下看:
simpleAccess: function(obj, subsc) {
return obj[subsc];
},
getJsonAccessor: function(){
var re = /[\[\.]/;
return function(expr) {
try {
return(re.test(expr))
? new Function("obj", "return obj." + expr)
: function(obj){
return obj[expr];
};
} catch(e){}
return Ext.emptyFn;
};
}(),
取一对象的属性有两种方法,前面都已提及:
一、obj.xxxx
二、obj[xxxx]
这两种都行。但是,如果传过来一个对象,已知其对象的引用obj,但是有的只是它的属性名的字符串,这时就可以用第二种方法取出,但是,如属性名中含[],那么就不大方便了,又或者是属性又带属性,这事也只能用第一种方法。这两个函数正是为事而来。且看那getJsonAccessor,着实巧妙,函数返回一函数,这不是巧妙之处,这个我以前就见识了,关键在于new Function("obj","return "obj."+expr) 。多么巧妙啊。此之中巧,不足以言语道哉。
这下面就是真正的好戏了,看一看readRecords函数。
this.jsonData = o;
if(o.metaData){
delete this.ef;
this.meta = o.metaData;
this.recordType = Ext.data.Record.create(o.metaData.fields);
this.onMetaChange(this.meta, this.recordType, o);
}
定义一个jsonData属性以保存原始json对象。然后如果传过的json对象中就有metaData。那么,就用它自带的meta来取代JsonReader构造函数中所传入的meta。以原来自带的为主。这个功能方档未曾提及,但我辈不可不察也。
var s = this.meta, Record = this.recordType,
f = Record.prototype.fields, fi = f.items, fl = f.length;
有人不理解了,为什么非得这样呢?这是节省带宽啊。如果这些东西以后多说现几次,那么每个用户都要多下载一些东西,成千上万人能节省多少啊。
if (!this.ef) {
if(s.totalProperty) {
this.getTotal = this.getJsonAccessor(s.totalProperty);
}
if(s.successProperty) {
this.getSuccess = this.getJsonAccessor(s.successProperty);
}
this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;};
if (s.id) {
var g = this.getJsonAccessor(s.id);
this.getId = function(rec) {
var r = g(rec);
return (r === undefined || r === "") ? null : r;
};
} else {
this.getId = function(){return null;};
}
this.ef = [];
for(var i = 0; i < fl; i++){
f = fi[i];
var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
this.ef[i] = this.getJsonAccessor(map);
}
}
因为要根据meta.id、meta.root。这两值都是字符串,这就要用到前面定义的getJsonAccessor函数了。这儿正是来生成几个取json对象中属性的函数,如:getTotal、getSuccess、getRoot、getId、ef数组,一个ef数组就解决了属性映射的问题,真是漂亮。
var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
if(s.totalProperty){
var v = parseInt(this.getTotal(o), 10);
if(!isNaN(v)){
totalRecords = v;
}
}
if(s.successProperty){
var v = this.getSuccess(o);
if(v === false || v === 'false'){
success = false;
}
}
这儿是求totalRecords、success。有一事要注意:其中:
c = root.length, totalRecords = c
这上c后面要用来循环的,而totalRecords是要返回的,而后,又求了totalRecords,这个意思是:如果结果中没有 totalProperty这一属性,那么就自动求取,如果存在,则以定义的totalProperty为主,由此可见,totalProperty是可有可无的。这个问题文档不曾见之。诸位可无忧矣。
var records = [];
for(var i = 0; i < c; i++){
var n = root[i];
var values = {};
var id = this.getId(n);
for(var j = 0; j < fl; j++){
f = fi[j];
var v = this.ef[j](n);
values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, n);
}
var record = new Record(values, id);
record.json = n;
records[i] = record;
}
return {
success : success,
records : records,
totalRecords : totalRecords
};
这是剩余的代码了,由for(var i = 0; i < c; i++)可知,循环的时候还是用root.length的。而不是totalProperty。这个要分清,事实上,totalProperty只是直接返回罢了,未做任何改动。里面就转化成Record了。其中,这个ef数组用得巧妙。类型转化用了convert。这个东西前文已讲,不足道哉。
var record = new Record(values, id);
id=this.getId(n),可见啦,id并非前文所说的主键,它只是一个用来做客户端唯一编号的东西,如对此有疑,可见于Ext.data.Record类。
record.json = n,json这个属性我在Ext.data.Record类中并未曾得见,诸君注意了,这个东西也许会有用。另外,readRecords返回的不只是一个records数组,而是一个json对象,包含success、records、totalRecords。
至此,JsonReader源代码分析完毕,呵呵,因为这个类代码量较少,故讲得详细。
分享到:
相关推荐
reader: new Ext.data.JsonReader({}, PersonRecord), remoteSort: true }); ``` 在这个例子中,当`store`加载数据时,会自动将`sort`和`dir`参数发送到服务器端。 #### 六、从store中获取数据 从`Ext.data....
关于这个原因有很多种,我只说下我遇到的 我这样 ... this.reader = new Ext.data.JsonReader( { totalProperty: ‘results’, root: ‘rows’, id:’docid’, fields: [‘docid’, ‘extention’,’docname’, ‘autho
var reader = new Ext.data.JsonReader({totalProperty:'totalProperty',root:'root'},record); store = new Ext.data.Store({ proxy:proxy, reader:reader }); //尾 分页 var pagebar = new Ext....
33、Ext.data.JsonReader类 …………… 26 34、Ext.data.XmlReader类 …………… 27 35、Ext.data.Store类 …………………… 28 36、Ext.data.GroupingStore类 ………… 32 37、Ext.data.SimpleStore类 ………… 34 ...
7. Ext.data.JsonReader篇一 12 8. Ext.data.JsonReader篇二 15 9. Ext.data.HttpProxy篇 19 10. Ext.data.Connection篇一 20 11. Ext.data.Connection篇二 24 12. Ext.Updater篇一 26 13. Ext.Updater篇二 27 14. ...
- `Ext.data.JsonReader.read(response, options)`:读取数据。 #### 三十四、Ext.data.XmlReader类(第27页) - **概述**:Ext.data.XmlReader类用于解析XML格式的数据。 - **常用方法**: - `new Ext.data....
33、Ext.data.JsonReader类 …………… 26 34、Ext.data.XmlReader类 …………… 27 35、Ext.data.Store类 …………………… 28 36、Ext.data.GroupingStore类 ………… 32 37、Ext.data.SimpleStore类 ………… 34 ...
- `Ext.data.JsonReader.read(response)`: 读取JSON数据。 #### 34. Ext.data.XmlReader 类 (P.27) - **概述**:读取XML格式的数据。 - **常用方法**: - `Ext.data.XmlReader.read(response)`: 读取XML数据。 ##...
4. **配置Reader**:设置数据读取器(Reader),如`Ext.data.JsonReader`,定义如何解析服务器返回的JSON数据。 5. **绑定到GridPanel**:将PagingStore与GridPanel关联,GridPanel会根据PagingStore的数据自动渲染...
13.6.3 Ext.data.JsonReader 13.6.4 Ext.data.XmlReader 13.7 Ext.ux.DWR 13.7.1 Ext.data.DwrProxy 13.7.2 Ext.data.DWRTreeLoader 13.7.4 Web服务端配置 13.7.5 服务层接口 第14章 ExtJS扩展 14.1 利用Ext...
- **Ext.data.JsonReader篇**:`Ext.data.JsonReader`是专门用于解析JSON数据的类,它能够将JSON字符串转换为JavaScript对象,便于进一步处理。 - **Ext.data.HttpProxy篇**:这部分介绍了`Ext.data.HttpProxy`,它...
13.6.3 Ext.data.JsonReader 13.6.4 Ext.data.XmlReader 13.7 Ext.ux.DWR 13.7.1 Ext.data.DwrProxy 13.7.2 Ext.data.DWRTreeLoader 13.7.4 Web服务端配置 13.7.5 服务层接口 第14章 ExtJS扩展 14.1 利用Ext...
reader: new Ext.data.JsonReader({totalProperty: 'totalProperty', root: 'root'}, ...) }); ``` 总结起来,Ext Js通过其丰富的组件库和数据绑定机制,极大地简化了前端开发,使得开发者可以高效地构建功能...
reader: new Ext.data.JsonReader({ id: 'listId', fields: tx.data.List }) }); this.conn = tx.data.conn; // Ext.sql.Proxy for managing Sqlite persistence this.proxy = new Ext.sql.Proxy(tx.data....
29. **Ext.data.ArrayReader类**、**JsonReader类**和**XmlReader类**:不同数据格式(数组、JSON、XML)的特定数据读取器。 30. **Ext.data.Store类**:数据存储,管理数据集,与DataProxy和DataReader交互。 31....
7. **Ext.data.JsonReader篇** JsonReader解析JSON格式的数据,将其转化为Store可用的记录集。理解JsonReader的配置项,如root、idProperty等,能确保数据正确地被Store接收和处理。 8. **Ext.data.HttpProxy篇** ...