Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ExtJS-使用JsonReader对复杂对象进行空安全检索_Extjs - Fatal编程技术网

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

ExtJS-使用JsonReader对复杂对象进行空安全检索,extjs,Extjs,我使用JsonReader将Json数据映射到网格/表单中使用的变量。后端是Java,有一些复杂的对象,我将它们Jsonify并传递给ExtJS前端。 这是我的JsonReader的一部分,它试图检索嵌套对象- {name:'status', type: 'string', mapping: 'status.name'} 当status有一个值(在服务器中不是null)时,这可以正常工作,但当status为null时,网格加载失败。目前,我所做的工作是在null的情况下从服务器发送一个空对象,

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

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

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

我可以想到两种可能性——一种是有文档记录的,另一种是无文档记录的:

  • 使用以下的
    convert()
    -机制:

  • mapping
    属性还可以使用提取器函数(这是未记录的,因此依赖它可能有点风险):


  • 请改用此安全的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;
            };
        }())
    });
    
    您可以在此处找到测试数据的工作示例:

    您是否已经找到了错误发生的确切位置?(通过切换到
    ext all debug.js
    并使用Firebug,例如。)@Tommi这是因为状态未定义,
    JsonReader
    正在尝试使用
    status.name
    提取数据,即,
    undefined.name
    @Lionel Chan是的,我理解,但我问它是否知道(在ExtJS代码中)的位置这正是导致“网格加载失败”的原因。@Tommi在我的localhost中复制,网格只是呈现为空,没有任何错误。我认为背后的原因是因为字段未定义,而JsonReader抑制了它。谢谢!由于生成的测试不是类型安全的,所以“0”(零)值返回为null,因此我不得不做一些微调。我修改了join方法,用Ext.isEmpty()将路径中的每个字段包装起来,从而修复了这个问题。。。结果='(!Ext.isEmpty('+a.join(')和&!Ext.isEmpty(')+')?'+dataName+'.+map+':null';
    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];
            };
        };
    }()
    });
    
    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;
            };
        }())
    });
    
    {
        root: [{
            id: 1,
            name: {
                name: "John",
                phone: "123"
            },          
        },
        {
            id: 4,
            name: null,         
        },
        ]
    }