您的位置:首页 > Web前端 > JavaScript

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

2009-11-06 10:55 260 查看
http://hi.baidu.com/%CE%CF%C5%A3%CD%F8%C2%E7/blog/item/ac99b5ee0c330ce8cf1b3ee2.html

有了上一篇中所讲内容,一般情况下就可以应付了,不过,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源代码分析完毕,呵呵,因为这个类代码量较少,故讲得详细。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: