2014-03-25 16 views
1

我試圖處理與ExtJS4嵌套結構的JSON。請不要像here 這樣回答,因爲這是錯誤的答案。我使用expandData: true與模型映射,它對我來說很好。ExtJS 4作家爲嵌套JSON與數組

我期望的問題是一個字段是對象數組。所以,這裏是我的代碼示例:

Ext.define('EdiWebUI.model.Document', { 
    extend: 'Ext.data.Model', 
    fields: [ 
    {name: 'document_header_documentReceiveDateTime', mapping: 'document.header.documentReceiveDateTime', type: 'string'}, 
    {name: 'document_header_documentProcessDateTime', mapping: 'document.header.documentProcessDateTime', type: 'string'}, 
    {name: 'document_header_documentID', mapping: 'document.header.documentID', type: 'string'}, 
    ... 
    {name: 'lines', type: 'auto'}, 
    ... 
    {name: 'attachments_documentFile_fileName', mapping: 'attachments.documentFile.fileName', type: 'string'}, 
    {name: 'attachments_documentFile_content', mapping: 'attachments.documentFile.content', type: 'string'} 
    ], 
    hasMany: [ 
    {model: 'DocumentLines', name: 'lines', associationKey: 'lines'} 
    ], 
    proxy: { 
    type: 'rest', 
    url: '/document', 
    reader: { 
     type: 'json', 
     root: 'data' 
    }, 
    writer: { 
     expandData: true, 
     writeAllFields: true, 
     nameProperty: 'mapping' 
    } 
    } 
}); 

Ext.define('DocumentLines',{ 
    extend: 'Ext.data.Model', 
    fields: [ 
    {'name': 'line_lineItem_lineNumber', mapping: 'line.lineItem.lineNumber', type: 'string'}, 
    {'name': 'line_lineItem_orderedQuantity', mapping: 'line.lineItem.orderedQuantity', type: 'string'}, 
    {'name': 'line_lineItem_orderedUnitPackSize', mapping: 'line.lineItem.orderedUnitPackSize', type: 'string'}, 
    ... 
}); 

所以,它的工作以及閱讀JSON像這樣的時候:

{ 
    "data": { 
    "document": { 
     "header": { 
     "documentReceiveDateTime": "2014-03-25T08:34:24", 
     "documentProcessDateTime": "2014-03-25T08:44:51", 
     "documentID": "83701540", 
     ..., 
     "lines": [ 
      { 
      "line": { 
       "lineItem": { 
       "lineNumber": "1", 
       "orderedQuantity": "5.000", 
       "orderedUnitPackSize": "1.000" 
       } 
      } 
      }, 
      { 
      "line": { 
       "lineItem": { 
       "lineNumber": "2", 
       "orderedQuantity": "4.000", 
       "orderedUnitPackSize": "1.000" 
       } 
      } 
      } 
     ] 
     ... 

,但我不能讓作家解析線。當我修整保存在我的文檔,我已經有一個像這樣的輸出:

{ lines: 
    [ { line_lineItem_lineNumber: 1, 
     line_lineItem_ean: '4352345234523', 
     line_lineItem_orderedQuantity: '45'} ], 

(文件其他部分擴張遠遠)

所以,這裏是一個問題:有沒有一種方法,使它按我的需要工作? ...或者我應該在服務器端做一個詭計(就像我現在所做的那樣)...

在此先感謝。

回答

3

你有兩個選擇:

  • 正確的方法,這就是使用存儲功能:定義,以獲得您想要的JSON你dataWriter和代碼自己的函數。
  • 請勿使用商店更新記錄,創建所需的json並使用Ajax請求更新需要更新的記錄。

無論如何,兩種方式都使用Ajax,第一個應該是首選。

我會在同一個文件中定義我的作家如商店,是這樣的:

Ext.define('MyApp.custom.Writer',{ 
    /* 
    * Formats the data for each record before sending it to the server. 
    * This method should be overridden to format the data in a way that differs from the default. 
    */ 
    getRecordData: function(record) { 
     var data = {}; 
     /* 
     * Parse your record and give it whatever structure you need here.. 
     */ 
     data.lines = []; 
     return data; 
    } 
}); 

儘管你似乎在你的Json一個間接額外的水平,不necessarly所需要的「訂單項」爲您已在行< - > lineItem和lineItem < - >與由lineItem定義的對象之間具有一對一關係。但這是一個不同的問題。

+0

嗨,@Pierre!感謝您的回答。這與lineItem不是一對一的關係,因爲在line元素的內部和外部都允許有許多可選的元素(比如lineOrder,lineDelivery內部行和本地化與行相同),所以這不是錯誤,只是一個不好的例子:)...關於作家...重寫[getExpandedData](http://docs.sencha.com/extjs/4.2.1/#!/api/Ext。 data.writer。Json-method-getExpandedData)函數?據我瞭解,它不能通過配置選項來完成? –

+0

好的謝謝澄清。關於作者:1)如果你重寫,它會這樣做,因爲你將在你的應用程序中使用每個作家,所以在這種情況下更喜歡繼承2)getExpandedData是受保護的。 JavaScript是明智的,但它沒有什麼區別,但試圖將它看作是你不能真正使用的私有API。它可能會改變,而且在公共方法不被棄用的地方。 – Pierre

+0

所以,這是有效的!這是一個最終的解決方案:1)作爲一個非常懶惰的人,我剛剛從ext-all-debug.js拷貝了'getExpandedData'到我的自定義編寫器2的'getRecordData'中做了一些更正:a)爲開始'if(!Array.isArray(data))data = [data.getData()]; b)將if(item.hasOwnProperty(prop))'body包裝到另一個** if if語句if( Array.isArray(item [prop]))this.getRecordData(item [prop]);其他......身體......'c)改變'。' 'nameParts = prop.split'''''''''''' 因此,非常感謝您展示正確的方式......我相信他們應該將它添加到ExtJS中作爲一項功能:) –

0

我已經使用了上面的答案,但是想分享代碼,以便讓嘗試同樣事情的人更容易一些。

上面的Dr. Leevsey's Code對我很有幫助,但是它的缺點是它將所有內容放入數組中。對於我的項目來說,如果它返回一個對象(帶有子對象)並且在基對象不是數組的情況下不返回數組,那麼它會更好。

下面是代碼:

Ext.define('MyApp.util.customWriter', 
{ 
    extend: 'Ext.data.writer.Json', 
    getRecordData: function (record, operation) { 
     var data = record; 
     var me = this; 
     var toObject = function (name, value) { 
      var o = {}; 
      o[name] = value; 
      return o; 
     }; 
     var itemsToObject = function (item) { 
      for (prop in item) { 
       if (Array.isArray(item[prop])) { 
        me.getRecordData(item[prop]); 
       } 
       else { 
        if (item.hasOwnProperty(prop)) { 
         var nameParts = prop.split('.'); 
         var j = nameParts.length - 1; 
         if (j > 0) { 
          var tempObj = item[prop]; 
          for (; j > 0; j--) { 
           tempObj = me.toObject(nameParts[j], tempObj); 
          } 
          item[nameParts[0]] = item[nameParts[0]] || {}; 
          Ext.Object.merge(item[nameParts[0]], tempObj); 
          delete item[prop]; 
         } 
        } 
       } 
      } 
     }; 

     if (!Array.isArray(data)) { 
      data = data.getData(); 
      itemsToObject(data); 
     } 
     else { 
      var dataLength = data.length; 
      for (var i = 0; i < dataLength; i++) { 
       itemsToObject(data[i]); 
      } 
     } 

     return data; 
    } 
});