zoukankan      html  css  js  c++  java
  • ExtJs实践:支持“复杂”Json的JsonReader

    从服务端返回如下的JSON:

    {Id:2,Name:'Child1',Parent:{Id:1,Name:'Parent'}}

    定义了如下的JsonReader来准备显示角色列表,父角色的名称影射成ParentName:

    var myReader = new Ext.data.JsonReader({
        idProperty: 'id'          
        root: 'rows',             
        totalProperty: 'results', 
        
        fields: [
            {name: 'Id'},
            {name: 'Name'},
            {name: 'ParentName', mapping: 'Parent.Name'}
        ]    
    });

    当服务端传回来的JSON包含Parent,就如上面的JSON一样,这个reader能正常工作,但是当返回的JSON中不包含Parent或者Parent为null的时候,列表就不能正常显示了:

    {Id:2,Name:'Child1',Parent:null}

    大家可能已经猜到mapping:’Parent.Name’也许出了问题,对,Parent为null,怎么能访问Name属性呢,这个时候ParentName也应该是null。但是JsonReader并没有考虑到这种情况,查看了JsonReader的源代码,发现了下面这个方法:

        getJsonAccessor: function(){
            var re = /[\[\.]/;
            return function(expr) {
                try {
                    return(re.test(expr)) ?
                    new Function("obj", "return obj." + expr) :
                    function(obj){
                        return obj[expr];
                    };
                } catch(e){}
                return Ext.emptyFn;
            };
        }(),

    获取Json访问器方法,JsonReader会通过这个方法的根据fields设定获取一系列的如下的function:

    function(obj){
      return obj.Id;
    }
    
    function(obj){
      return obj.Name;
    }
    
    function(obj){
      return obj.Parent.Name;
    }

    大家看到问题了吧,就在obj.Parent.Name上,当Parent为null或者根本不存在的时候,程序到这里就终止了。要解决这个问题,我们就要修改这个获取Json访问器的方法,使它能返回如下的function:

    function(obj){
      try{
        return obj.Parent.Name;  
      }
      catch(e){}
      return undefined;
    }

    当然我们不能去修改ExtJs的源程序,使用继承来覆盖原来的getJsonAccessor:

    ComplexJsonReader = Ext.extend(Ext.data.JsonReader, {
        getJsonAccessor: function() {
            var re = /[\[\.]/;
            return function(expr) {
                try {
                    return (re.test(expr)) ?
                    new Function("obj", "try { return  obj." + expr + ";}catch(e){}return undefined;") :
                    function(obj) {
                        return obj[expr];
                    };
                } catch (e) { }
                return Ext.emptyFn;
            };
        } ()
        
    });

    但是,如果你的GridPanel使用的是JsonStore的话,那么将不能享受ComplexJsonReader,因为JsonStore是一个顽固分子,它在内部限定了reader只能是JsonReader:

    Ext.data.JsonStore = Ext.extend(Ext.data.Store, {
        /**
         * @cfg {Ext.data.DataReader} reader @hide
         */
        constructor: function(config){
            Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(config, {
                reader: new Ext.data.JsonReader(config)
            }));
        }
    });
    Ext.reg('jsonstore', Ext.data.JsonStore);

    所以你只能再派生一个ComplexJsonStore出来,但是不能从JsonStore继承,因为它很顽固,除了通过配置来设定reader之外,没有提供方法来设定,所以你想在它的构造函数调用之后再来替换掉reader,没有门,所以只能从Store继承:

    ComplexJsonStore = Ext.extend(Ext.data.Store, {
        constructor: function(config) {
            ComplexStore.superclass.constructor.call(this, Ext.apply(config, {
                reader: new ComplexJsonReader(config)
            }));
        }
    });

    嗯,ComplexJsonStore也很顽固,当然你也可以改变一下,让它不那么顽固 :)。

    “复杂”Json?谁有更好的叫法?

  • 相关阅读:
    <p>1、查询端口号占用,根据端口查看进程信息</p>
    CentOS查询端口占用和清除端口占用的程序
    Spring Boot Maven 打包可执行Jar文件!
    linux下运行jar
    maven 工程mybatis自动生成实体类
    java反射教程
    SQL Server 文件和文件组
    Angular CLI 使用教程指南参考
    mac osx 下 浏览器 开启 java
    es 查询分词字段为空的数据
  • 原文地址:https://www.cnblogs.com/tubo/p/1572991.html
Copyright © 2011-2022 走看看