2013-02-16 4 views
13

Je souhaite créer un clone d'un modèle en cours d'édition.Modèle de clone Ember pour nouvel enregistrement

J'ai trouvé quelques façons qui fonctionnent presque. Mais aucun n'est parfait.

1) model.get('data.attributes') obtient tous les attributs à l'exception des relations sous forme camelCase, génère un nouvel enregistrement bien mais les relations sont manquantes bien sûr.

2) model.serialize() génère un objet JSON, avec tous les attributs, y compris les relations. Mais createRecord ne traitera pas bien puisque l'objet ne notationCamel (attributs avec des underscores comme first_name ne seront pas traitées)

Après mon clone a été créé, je veux transaction.createRecord(App.Document, myNewModelObject) changement/définir quelques attributs et enfin commit(). Quelqu'un a un aperçu de la façon de faire cela?

Répondre

0

Voici une réponse mise à jour, il ne gère toujours pas les relations 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)); 
     } 
    }); 
    }); 
} 

Et voici comment je l'utilise:

// 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

J'ai maintenant un exemple d'ajouter des éléments belongsTo aussi: http://stackoverflow.com/q/20477301/1153884 – DelphiLynx

+0

Avez-vous trouvé comment faire hasMany? J'ai fini par faire cela qui semble fonctionner, mais ce n'est probablement pas le meilleur moyen. 'this.eachRelationship (fonction (touche, relation) { self._data [key] .foreach (fonction (obj) { newRecord.get (clé) .addObject (obj); })} );' –

2

Que diriez-vous en utilisant la méthode toJSON() au lieu de serialize() comme celui-ci

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

3

Maintenant, nous avons un add- sur pour copier les modèles ember-cli-copyable

W vec cet add-on, il suffit d'ajouter le mélange dans Copyable au modèle cible qui doit être copié et utiliser la méthode de copie

Exemple du module 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

La façon la plus simple que je trouve:

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

Voici la façon simple de cloner votre Ember modèle avec des relations. fonctionne bien.

Créer un mixin Copiable comme,

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); 
    } 
}); 

Ajouter le mixin dans votre modèle,

Note: Si vous voulez cloner votre modèle d'enfant alors, vous devez inclure le mixin chez l'enfant modèle ainsi

USAGES:

  1. Relation: YOURMODEL.copy (true)
  2. Sans lien: YOURMODEL.copie()
0

Cela permettra également de résoudre mon problème

`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' renvoie Promise. donc vous ne pouvez pas faire 'model.toJSON' immédiatement. – kumkanillam

Questions connexes