ExtJS-使用JsonReader进行空安全的复杂对象检索

问题描述

|| 我正在使用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/