2011-04-19 87 views
3

我正在使用JsonReader將Json數據映射到要在網格/表單中使用的變量。後端是Java,並且有一些複雜的對象,我將它們傳遞給ExtJS前端。 這是我JsonReader的一部分,它試圖獲取一個嵌套的對象 -ExtJS - 使用JsonReader對複雜對象進行null安全檢索

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

能正常工作狀態時有一個值(在服務器不爲空),但是當狀態是空的電網負荷失敗。目前我所做的工作是在發送null的情況下從服務器發送一個空對象,但我認爲應該有一種方法可以在ExtJS中處理這個問題。請在ExtJS方面提出更好的解決方案。

+0

你是否已經精確地定位錯誤發生在哪裏? (例如,切換到'ext-all-debug.js'並使用Firebug) – Tommi 2011-04-19 05:40:38

+0

@Tommi這是因爲狀態是未定義的,並且'JsonReader'試圖使用'status.name'來提取數據,它是,'undefined.name'。 – 2011-04-19 06:18:06

+0

@Lionel Chan是的我明白,但是我問是否知道在哪裏(在ExtJS代碼中)恰恰會導致「網格加載失敗」。 – Tommi 2011-04-19 07:29:57

回答

4

我能想到的兩種可能性 - 一個記錄,一個無證:

  1. 使用convert() -mechanism的Ext.data.Field

    { 
        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; 
         } 
        } 
    } 
    
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]; 
     }; 
    }; 
}() 
}); 
0

我已經改變斯拉瓦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/

+0

感謝您的支持!由於生成的測試不是類型安全的,因此必須進行微調,因爲'0'(零)值返回爲null。我通過更改連接方法來修復它,以便用Ext.isEmpty()包裝路徑中的每個字段... result ='(!Ext.isEmpty('+ a.join(')&&!Ext.isEmpty(' )+'))? '+ dataName +'。' + map +':null'; – JamieB 2012-11-29 14:23:19