我正在使用JsonReader将Json数据映射到要在网格/表单中使用的变量。后端是Java,有一些复杂的对象我Jsonify并传递给ExtJS前端。 这是我的JsonReader的一部分,它试图检索嵌套对象 -
{name:'status', type: 'string', mapping: 'status.name'}
当status具有值(在服务器中不为null)时,这可以正常工作,但当status为null时,网格加载失败。目前我的工作是在null的情况下从服务器发送一个空对象,但我认为应该有一种方法在ExtJS中处理它。请在ExtJS方面建议更好的解决方案。
答案 0 :(得分:4)
我可以想到两种可能性 - 一种是有记录的,一种是未记录的:
使用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;
}
}
}
答案 1 :(得分:0)
请改用此安全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];
};
};
}()
});
答案 2 :(得分:0)
我改变了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/