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

时间:2011-04-19 05:27:12

标签: extjs

我正在使用JsonReader将Json数据映射到要在网格/表单中使用的变量。后端是Java,有一些复杂的对象我Jsonify并传递给ExtJS前端。 这是我的JsonReader的一部分,它试图检索嵌套对象 -

{name:'status', type: 'string', mapping: 'status.name'}

当status具有值(在服务器中不为null)时,这可以正常工作,但当status为null时,网格加载失败。目前我的工作是在null的情况下从服务器发送一个空对象,但我认为应该有一种方法在ExtJS中处理它。请在ExtJS方面建议更好的解决方案。

3 个答案:

答案 0 :(得分:4)

我可以想到两种可能性 - 一种是有记录的,一种是未记录的:

  1. 使用Ext.data.Fieldconvert()机制:

    {
        name:'status', 
        mapping: 'status',
        convert: function(status, data) {
            if (!Ext.isEmpty(status) && status.name) {
                return status.name;
            } else {
                return null;
            }
        }
    }
    
  2. 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/