ExtJs实践:支持“复杂”Json的JsonReader
2009-09-25 00:00:00 来源:WEB开发网从服务端返回如下的JSON:
{Id:2,Name:'Child1',Parent:{Id:1,Name:'Parent'}}
定义了如下的JsonReader来准备显示角色列表,父角色的名称影射成ParentName:
var myReader = new Ext.data.JsonReader({
idProperty: 'id'
root: 'rows',
totalProperty: 'results',
fields: [
{name: 'Id'},
{name: 'Name'},
{name: 'ParentName', mapping: 'Parent.Name'}
]
});
当服务端传回来的JSON包含Parent,就如上面的JSON一样,这个reader能正常工作,但是当返回的JSON中不包含Parent或者Parent为null的时候,列表就不能正常显示了:
{Id:2,Name:'Child1',Parent:null}
大家可能已经猜到mapping:’Parent.Name’也许出了问题,对,Parent为null,怎么能访问Name属性呢,这个时候 ParentName也应该是null。但是JsonReader并没有考虑到这种情况,查看了JsonReader的源代码,发现了下面这个方法:
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;
};
}(),
获取Json访问器方法,JsonReader会通过这个方法的根据fields设定获取一系列的如下的function:
function(obj){
return obj.Id;
}
function(obj){
return obj.Name;
}
function(obj){
return obj.Parent.Name;
}
大家看到问题了吧,就在obj.Parent.Name上,当Parent为null或者根本不存在的时候,程序到这里就终止了。要解决这个问题,我们就要修改这个获取Json访问器的方法,使它能返回如下的function:
function(obj){
try{
return obj.Parent.Name;
}
catch(e){}
return undefined;
}
当然我们不能去修改ExtJs的源程序,使用继承来覆盖原来的getJsonAccessor:
ComplexJsonReader = Ext.extend(Ext.data.JsonReader, {
getJsonAccessor: function() {
var re = /[\[\.]/;
return function(expr) {
try {
return (re.test(expr)) ?
new Function("obj", "try { return obj." + expr + ";}catch(e){}return undefined;") :
function(obj) {
return obj[expr];
};
} catch (e) { }
return Ext.emptyFn;
};
} ()
});
但是,如果你的GridPanel使用的是JsonStore的话,那么将不能享受ComplexJsonReader,因为JsonStore是一个顽固分子,它在内部限定了reader只能是JsonReader:
Ext.data.JsonStore = Ext.extend(Ext.data.Store, {
/**
* @cfg {Ext.data.DataReader} reader @hide
*/
constructor: function(config){
Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(config, {
reader: new Ext.data.JsonReader(config)
}));
}
});
Ext.reg('jsonstore', Ext.data.JsonStore);
所以你只能再派生一个ComplexJsonStore出来,但是不能从JsonStore继承,因为它很顽固,除了通过配置来设定reader之外,没有提供方法来设定,所以你想在它的构造函数调用之后再来替换掉reader,没有门,所以只能从Store继承:
ComplexJsonStore = Ext.extend(Ext.data.Store, {
constructor: function(config) {
ComplexStore.superclass.constructor.call(this, Ext.apply(config, {
reader: new ComplexJsonReader(config)
}));
}
});
嗯,ComplexJsonStore也很顽固,当然你也可以改变一下,让它不那么顽固 :)。
“复杂”Json?谁有更好的叫法?
- ››ExtJs Grid 合计 [Ext | GridPanel | GridSummary...
- ››ExtJS中如何扩展自定义的类
- ››支持 Symbian 平台的开发者只有四分之一
- ››支持电骡视频点播 迅雷泛播放体验
- ››支持Win 7 Vista 不开迅雷接管高速下载
- ››支持换肤功能的窗口实例
- ››支持iPhone的免费VPN:VPN98
- ››支持PDF阅读!美图看看新版试用
- ››支持Windows CE和Android 2.1双系统的Viliv Prime...
- ››支持Flash Windows Mobile 手机全功能浏览器
- ››Extjs列表详细信息窗口新建后自动加载解决方法
- ››支持 Wi-Fi MOTO 第9款 Android 手机ME508曝光
赞助商链接