问题描述
||
我正在使用JsonReader将Json数据映射到要在网格/表单中使用的变量。后端使用Java,我将Jsonify并传递给ExtJS前端的对象很复杂。
这是我的JsonReader的一部分,它尝试检索嵌套对象-
{name:\'status\',type: \'string\',mapping: \'status.name\'}
当status具有值(服务器中不为null)时,此方法运行良好,但是当status为null时,网格加载失败。目前,我要解决的问题是在服务器为null的情况下从服务器发送一个空对象,但是我认为应该有一种方法可以在ExtJS中进行处理。请在ExtJS方面提出更好的解决方案。解决方法
我可以想到两种可能性-一种记录在案,一种未记录在案:
使用
Ext.data.Field
的convert()
机制:
{
name:\'status\',mapping: \'status\',convert: function(status,data) {
if (!Ext.isEmpty(status) && status.name) {
return status.name;
} else {
return null;
}
}
}
mapping
属性还可以采用提取函数(未记录,因此依赖于此可能有点冒险):
{
name:\'status\',mapping: function(data) {
if (data.status && data.status.name) {
return data.status.name;
} else {
return null;
}
}
}
,请使用此安全的json阅读器:
Ext.define(\'Ext.data.reader.SafeJson\',{
extend: \'Ext.data.reader.Json\',alias : \'reader.safe\',/**
* @private
* Returns an accessor function for the given property string. Gives support for properties such as the following:
* \'someProperty\'
* \'some.property\'
* \'some[\"property\"]\'
* This is used by buildExtractors to create optimized extractor functions when casting raw data into model instances.
*/
createAccessor: function() {
var re = /[\\[\\.]/;
return function(expr) {
if (Ext.isEmpty(expr)) {
return Ext.emptyFn;
}
if (Ext.isFunction(expr)) {
return expr;
}
if (this.useSimpleAccessors !== true) {
var i = String(expr).search(re);
if (i >= 0) {
if (i > 0) { // Check all property chain for existence. Return null if any level does not exist.
var a = [];
var l = expr.split(\'.\');
var r = \'\';
for (var w in l) {
r = r + \'.\' + l[w];
a.push(\'obj\' + r);
}
var v = \"(\" + a.join(\" && \") + \") ? obj.\" + expr + \" : null\";
return Ext.functionFactory(\'obj\',\'return (\' + v + \')\');
} else {
return Ext.functionFactory(\'obj\',\'return obj\' + expr);
}
}
}
return function(obj) {
return obj[expr];
};
};
}()
});
,我更改了Slava Nadvorny的示例,以使其完全适用于ExtJS 4.1.1。
下面是Ext.data.reader.Json的新扩展类:
Ext.define(\'Ext.data.reader.SafeJson\',{
extend: \'Ext.data.reader.Json\',alias : \'reader.safejson\',/**
* @private
* Returns an accessor function for the given property string. Gives support for properties such as the following:
* \'someProperty\'
* \'some.property\'
* \'some[\"property\"]\'
* This is used by buildExtractors to create optimized extractor functions when casting raw data into model instances.
*/
createAccessor: (function() {
var re = /[\\[\\.]/;
return function(expr) {
if (Ext.isEmpty(expr)) {
return Ext.emptyFn;
}
if (Ext.isFunction(expr)) {
return expr;
}
if (this.useSimpleAccessors !== true) {
var i = String(expr).search(re);
if (i >= 0) {
if (i > 0) { // Check all property chain for existence. Return null if any level does not exist.
var a = [];
var l = expr.split(\'.\');
var r = \'\';
for (var w in l) {
r = r + \'.\' + l[w];
a.push(\'obj\' + r);
}
var v = \"(\" + a.join(\" && \") + \") ? obj.\" + expr + \" : null\";
return Ext.functionFactory(\'obj\',\'return (\' + v + \')\');
} else {
return Ext.functionFactory(\'obj\',\'return obj\' + (i > 0 ? \'.\' : \'\') + expr);
}
}
}
return function(obj) {
return obj[expr];
};
};
}()),/**
* @private
* @method
* Returns an accessor expression for the passed Field. Gives support for properties such as the following:
*
* - \'someProperty\'
* - \'some.property\'
* - \'some[\"property\"]\'
*
* This is used by buildExtractors to create optimized on extractor function which converts raw data into model instances.
*/
createFieldAccessExpression: (function() {
var re = /[\\[\\.]/;
return function(field,fieldVarName,dataName) {
var me = this,hasMap = (field.mapping !== null),map = hasMap ? field.mapping : field.name,result,operatorSearch;
if (typeof map === \'function\') {
result = fieldVarName + \'.mapping(\' + dataName + \',this)\';
} else if (this.useSimpleAccessors === true || ((operatorSearch = String(map).search(re)) < 0)) {
if (!hasMap || isNaN(map)) {
// If we don\'t provide a mapping,we may have a field name that is numeric
map = \'\"\' + map + \'\"\';
}
result = dataName + \"[\" + map + \"]\";
} else {
if (operatorSearch > 0) {
var a = [];
var l = map.split(\'.\');
var r = \'\';
for (var w in l) {
r = r + \'.\' + l[w];
a.push(dataName + r);
}
result = \"(\"+a.join(\" && \")+\") ? \"+dataName+\".\"+map+\" : null\";
} else {
result = dataName + map;
}
}
return result;
};
}())
});
因此,您可以成功处理具有空节点的嵌套JSON数据。
JSON范例:
{
root: [{
id: 1,name: {
name: \"John\",phone: \"123\"
},},{
id: 4,name: null,]
}
您可以在此处找到有关测试数据的工作示例:
http://jsfiddle.net/8Ftag/