2013-02-16 10 views
13

Voglio fare un clone di un modello attualmente in fase di modifica.Modello clone di ambra per il nuovo record

Ho trovato un paio di modi che quasi funzionano. Ma nessuno dei due è perfetto.

1) model.get('data.attributes') ottiene tutti gli attributi tranne le relazioni in forma camelCase, genera una nuova ammenda record ma le relazioni mancano ovviamente.

2) model.serialize() genera un oggetto JSON, con tutti gli attributi comprese le relazioni. Ma createRecord non gestirà bene dal momento che l'oggetto non viene formato camelCase (attributi di sottolineatura come first_name non sarà trattata)

Dopo il mio clone è stata creata voglio transaction.createRecord(App.Document, myNewModelObject) cambiamento/set un paio di attributi e infine commit(). Qualcuno ha qualche idea su come farlo?

risposta

0

Ecco una risposta aggiornata, non gestisce ancora le relazioni hasMany.

cloneBelongsTo: function(fromModel, toModel) { 
    var relationships; 
    relationships = Em.get(fromModel.constructor, 'relationships'); 
    return relationships.forEach(function(relationshipType) { 
    var _relType; 
    _relType = relationships.get(relationshipType); 
    return _relType.forEach(function(relationship) { 
     var name, relModel; 
     relModel = Em.get(fromModel, relationship.name); 
     if (relationship.kind === 'belongsTo' && relModel !== null) { 
     name = relationship.name; 
     return toModel.set(name, fromModel.get(name)); 
     } 
    }); 
    }); 
} 

Ed ecco come lo uso:

// create a JSON representation of the old model 
var newModel = oldModel.toJSON(); 
// set the properties you want to alter 
newModel.public = false; 
// create a new record 
newDocument = store.createRecord('document', newModel); 
// call the cloneBelongsTo method after the record is created 
cloneBelongsTo(model, newDocument); 
// finally save the new model 
newDocument.save(); 
+0

ho ora un esempio di aggiunta di elementi belongsTo anche: http://stackoverflow.com/q/20477301/1153884 – DelphiLynx

+0

Hai capito come fare hasMany? Ho finito per fare ciò che sembra funzionare, ma probabilmente non è il modo migliore. 'this.eachRelationship (function (chiave, relazione) { self._data [tasto] .forEach (function (obj) { newRecord.get (chiave) .addObject (obj); }) });' –

2

Come sull'utilizzo toJSON() invece il metodo di serialize() come questo

js transaction.createRecord(App.Document, model.toJSON());

3

Ora abbiamo un add per copiare i modelli ember-cli-copyable

W esimo questo add on, basta aggiungere il Copyable mix-in al modello di destinazione, che deve essere copiato e utilizzare il metodo copia

Esempio dal add-on site

import Copyable from 'ember-cli-copyable'; 

Account = DS.Model.extend(Copyable, { 
    name: DS.attr('string'), 
    playlists: DS.hasMany('playList'), 
    favoriteSong: DS.belongsTo('song') 
}); 

PlayList = DS.Model.extend(Copyable, { 
    name: DS.attr('string'), 
    songs: DS.hasMany('song'), 
}); 

//notice how Song does not extend Copyable 
Song = DS.Model.extend({ 
    name: DS.attr('string'), 
    artist: DS.belongsTo('artist'), 
}); 
//now the model can be copied as below 
this.get('currentAccount.id') // => 1 
this.get('currentAccount.name') // => 'lazybensch' 
this.get('currentAccount.playlists.length') // => 5 
this.get('currentAccount.playlists.firstObject.id') // => 1 
this.get('currentAccount.favoriteSong.id') // => 1 

this.get('currentAccount').copy().then(function(copy) { 

    copy.get('id') // => 2 (differs from currentAccount) 
    copy.get('name') // => 'lazybensch' 
    copy.get('playlists.length') // => 5 
    copy.get('playlists.firstObject.id') // => 6 (differs from currentAccount) 
    copy.get('favoriteSong.id') // => 1 (the same object as in currentAccount.favoriteSong) 

}); 
0

Modo più semplice che ho trovato:

function cloneModel(model) { 
    const root = model._internalModel.modelName; 
    const store = model.get('store'); 
    let attrs = model.toJSON(); 

    attrs.id = `clone-${attrs.id}`; 
    store.pushPayload({ 
    [root]: attrs 
    }); 
    return store.peekRecord(root, attrs.id); 
} 
0

Ecco il modo più semplice per clonare il vostro Ember Modello con le relazioni. funziona bene.

Creare un mixin copiabile come,

import Ember from 'ember'; 

export default Ember.Mixin.create(Ember.Copyable, { 

    copy(deepClone) { 
     var model = this, attrs = model.toJSON(), class_type = model.constructor; 
     var root = Ember.String.decamelize(class_type.toString().split(':')[1]); 

     if(deepClone) { 
      this.eachRelationship(function(key, relationship){ 
       if (relationship.kind == 'belongsTo') { 
        attrs[key] = model.get(key).copy(true); 
       } else if(relationship.kind == 'hasMany' && Ember.isArray(attrs[key])) { 
        attrs[key].splice(0); 
        model.get(key).forEach(function(obj) { 
         attrs[key].addObject(obj.copy(true)); 
        }); 
       } 
      }); 
     } 
     return this.store.createRecord(root, attrs); 
    } 
}); 

Aggiungere il mixin nel modello,

Nota: Se si desidera clonare il modello del bambino, allora, è necessario includere il mixin nel bambino modello come pure

USO:

  1. Con relazione: YOURMODEL.copy (true)
  2. Senza relazione: YOURMODEL.copia()
0

Questo sarà anche risolvere il mio problema

`Account = DS.Model.extend({ 
    name: DS.attr('string'), 
    playlists: DS.hasMany('playList'), 
    favoriteSong: DS.belongsTo('song') 
}); 

Duplicate= Ember.Object.extend({}); 

TemporaryRoute = Ember.Route.extend({ 
model : function(){ 
     var model = this.store.findAll('account'); 
     var json = model.toJSON(); 
     var duplicateModel = Duplicate.create(json); 
     this.set('duplicateModel', duplicateModel); 
     return model; 
} 
});` 
+0

'findAll' restituisce Promise. quindi non puoi fare 'model.toJSON' immediatamente. – kumkanillam

Problemi correlati