ExtJs実践:「複雑」JsonをサポートするJsonReader

5516 ワード

サービス側から次の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を使用している場合は、JsonStoreは頑固な分子であり、readerはJsonReaderに限られているため、ComplexJsonReaderを楽しむことはできません.
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);

だからあなたはもう1つの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?誰がもっと良い呼び方がありますか?