2014-02-25 45 views
2

鑑於是這樣嵌套模型結構:ExtJS的4 - 模型包含其它模型不進行身份關係

Model Website 
+ id 
+ name 
+ images[] // List of Image instances 

Model Image 
+ imageName 
+ imageUrl 

響應的序列化版本看起來像:

{ 
"id": 4711, 
"name": "Some name", 
"images" [ 
    {"imageName": "Beach", "imageUrl": "http://example.com/whatever.jpg"}, 
    ... 
] 
} 

此嵌套模型集合是堅持在文檔存儲中,並且通過Website.id請求返回。

圖像的嵌套列表沒有by-id關係,因爲它們直接在父模型中作爲列表持久保存。據我所知,Ext.data.Model中的經典關係通過一個by-id關係來引用相關模型。

問題是:有沒有什麼辦法可以告訴父模型爲圖像列表中的每個孩子使用圖像模型?

回答

2

作爲第一步,可以讓你的圖像數據被加載到模型中使用的auto字段類型:

Ext.define('My.Model', { 
    extend: 'Ext.data.Model' 

    ,fields: [ 
     {name: 'images', type: 'auto'} 
     // ... other fields 
    } 
}); 

然後:

myModel.get('images'); 

應返回:

[ 
    {"imageName": "Beach", "imageUrl": "http://example.com/whatever.jpg"}, 
    ... 
] 

從那裏,你理論上應該能夠實現一個完全自動化的解決方案通過這些數據創建模型,以及 - 最難的部分 - 嘗試將這些創建的記錄和父級模型中的子級數據保持同步。但這是一個非常複雜的入侵,並且必須涵蓋Ext代碼庫中的很多入口點。作爲一個例子,我曾經試圖做到「有一個」關係,並且代表a lot of code。因此,我從來沒有花時間來鞏固這些代碼,並最終從未使用它。

我寧願主張一個簡單的本地(對模型)的解決方案。您可以在模型中添加一個簡單的方法來獲取圖像作爲記錄。例如:

Ext.define('My.Model', { 

    // ... 

    ,getImages: function() { 
     var store = this.imageStore; 
     if (!store) { 
      store = new Ext.data.Store({ 
       model: 'My.ImageModel' 
       ,data: this.get('images') || [] 
      }); 
      this.imageStore = store; 
     } 
     return store; 
    } 
}); 

爲相關模型創建存儲將使您無需使用代理和讀者。它還爲您提供了一個接近Ext默認的關聯的界面。

如果您需要支持爲同一父記錄多次加載圖像,可以勾選該字段的convert方法。

最後,您可能還需要處理關聯數據的客戶端修改,以便能夠將它們保存到服務器。如果您的關聯模型允許,您可以簡單地使用兒童商店的sync方法(並且不要忘記在同步回調中​​更新父模型的數據!)。但是,如果您的關聯模型沒有連接到服務器端的端點,您應該能夠掛接serialize方法以將數據保存在關聯存儲中(與存儲在父記錄中的數據相對)如果您在相關商店工作,則不會更新)。

這裏展示既是最後一個例子:

Ext.define('My.Model', { 
    extend: 'Ext.data.Model' 

    ,fields: [ 
     { 
      name: 'images' 
      ,type: 'auto' 

      // enables associated data update 
      ,convert: function(data) { 
       var store = this.imageStore; 
       if (store) { 
        store.loadData(data || []); 
       } 
       return data; 
      } 

      // enables saving data from the associated store 
      ,serialize: function(value, record) { 
       var store = record.imageStore, 
       if (store) { 
        // care, the proxy we want is the associated model's one 
        var writer = store.proxy && store.proxy.writer; 
        if (writer) { 
         return Ext.Array.map(store.getRange(), function(record) { 
          return writer.getRecordData(record); 
         }); 
        } else { 
         // gross implementation, simply use the records data object 
         return Ext.pluck(store.getRange(), 'data'); 
        } 
       } else { 
        return record.get('images'); 
       } 
      } 
     } 

     // ... other fields 
    } 

    ,getImages: function() { 
     var store = this.imageStore; 
     if (!store) { 
      store = new Ext.data.Store({ 
       model: 'My.ImageModel' 
       ,data: this.get('images') || [] 
      }); 
      this.imageStore = store; 
     } 
     return store; 
    } 
}); 

請注意,我還沒有測試此代碼,所以它可能仍然包含一些錯誤。但我希望這將足以給你大概的概念!

+0

太棒了!感謝你的付出。我會在接下來的兩天內嘗試一下,我會回來的任何反饋。 –

+0

適合我的需求。再次謝謝你! –