2012-12-15 32 views
3

背景

最近Tom Dale announced「嵌入式加載現在回來了!」。不過,它似乎完全支持加載的情況。目前尚不清楚序列化嵌入式關聯是否仍在開發中,或者是否希望用戶通過構建自定義序列化程序來實現它們。如何序列化嵌入式數據中的關聯?

要求

的JSON我的嵌入式協會是這樣的:

{ 
    inputs: [ 
    { 
     id: 1, 
     name: "Favorite Color", 
     type: "SelectInput", 
     options: { 
     choices: [ 'red', 'green', 'yellow' ] 
     } 
    }, 
    { 
     id: 2, 
     name: "email", 
     type: "TextInput", 
     options: {} 
    } 
    ] 
} 

我相信「燼的方式」來表示這是建立一個自定義序列,將我的JSON轉換成模型,如:

App.Choice = DS.Model.extend({ 
    name: DS.attr('string'), 
    input: DS.belongsTo('App.Input') 
}); 

App.Input = DS.Model.extend({ 
    name: DS.attr('string'), 
    type: DS.attr('string'), 
    choices: DS.hasMany('App.Choice') 
}); 

嘗試性解決方案

在F下面的解決方案大多可以工作,但是感覺就像我必須「做錯了」一樣,因爲我不得不對逆向工程和子類化這麼多代碼。

Customizer.MyRESTAdapter = DS.RESTAdapter.extend({ 
    dirtyRecordsForAttributeChange: function(dirtySet, record, attributeName, newValue, oldValue) { 
    if(record.constructor === Customizer.Choice) { 
     if(newValue === oldValue) { return; } 

     var input = null; 
     if (attributeName == 'name') { 
     input = record.get('input'); 
     } 
     else if(attributeName == 'input') { 
     input = newValue; 
     } 
     if(input) { 
     dirtySet.add(input); 
     } 
    } 
    else { 
     this._super(dirtySet, record, attributeName, newValue, oldValue); 
    } 
    }, 

    dirtyRecordsForBelongsToChange: function(dirtySet, child, relationship) { 
    if(child.constructor === Customizer.Choice) { 
     var input = child.get('input'); 
     if(input) { 
     dirtySet.add(input); 
     } 
    } 
    else { 
     this._super(dirtySet, child, relationship); 
    } 
    }, 

    dirtyRecordsForHasManyChange: function(dirtySet, parent, relationship) { 
    this._super(dirtySet, parent, relationship); 
    } 
}); 

Customizer.MyRESTSerializer = DS.RESTSerializer.extend({ 
    init: function() { 
    this._super(); 
    this.mappings.set('Customizer.Input', { choices: { embedded: 'load' } }); 
    }, 

    extractEmbeddedHasMany: function(type, hash, key) { 
    if(type == Customizer.Input) { 
     if(!(hash['options'] && hash['options']['choices'])) { return null; } 

     var choices = []; 
     hash['options']['choices'].forEach(function(choice, i){ 
     var choiceId = hash['id'] + '_' + i; 
     var inputId = hash['id']; 
     choices[i] = { id: choiceId, input_id: inputId, name: choice }; 
     }); 
     return choices; 
    } 

    return this._super(type, hash, key); 
    }, 

    addHasMany: function(data, record, key, relationship) { 
    this._super(data, record, key, relationship); 

    if(key === 'choices') { 
     var choices = record.get('choices').map(function(choice){ 
     return choice.get('name'); 
     }); 
     data['options'] = data['options'] || {}; 
     data['options']['choices'] = choices; 
    } 
    } 

}); 

Customizer.store = DS.Store.create({ 
    revision: 10, 
    adapter: Customizer.MyRESTAdapter.create({ 
    namespace: 'api/v1', 
    bulkCommit: false, 
    serializer: Customizer.MyRESTSerializer 
    }) 
}) 

徵求反饋

  • 這是正確的道路?
  • 燼團隊是否正在積極研究一個更好的方法來做到這一點?

回答

0

我最終使用的http://mozmonkey.com/2013/12/serializing-embedded-relationships-ember-data-beta/的變化。在我的情況下,我將id添加到JSON中,或者如果它不髒,我只發送id自己。

class App.ApplicationSerializer extends DS.ActiveModelSerializer 
    # Based on http://mozmonkey.com/2013/12/serializing-embedded-relationships-ember-data-beta/ 
    # Also see http://discuss.emberjs.com/t/ember-data-beta-3-and-saving-hasmany-relationships-with-activemodelserializer`-and-rails/3167 
    serializeHasMany: (record, json, relationship) -> 
    key = relationship.key 
    hasManyRecords = Ember.get(record, key) 
    embed = relationship.options.embed 
    if embed && hasManyRecords 
     json[key] = [] 
     hasManyRecords.forEach (item, index) => 
     json[key].push @serializeItem(item, embed) 
    else 
     @._super(record, json, relationship) 

    serializeBelongsTo: (record, json, relationship) -> 
    key = relationship.key 
    belongsToRecord = Ember.get(record, key) 
    embed = relationship.options.embed 
    if embed 
     json[key] = @serializeItem(belongsToRecord, embed) 
    else 
     @._super(record, json, relationship) 

    serializeItem: (item, embed) -> 
    if embed == 'ifDirty' 
     if item.isDirty 
     data = item.serialize() 
     else 
     data = {} 
     data['id'] = item.id 
    else if embed == 'always' 
     data = item.serialize() 
     data['id'] = item.id 
    else 
     null 
    data 
相關問題