How can I clone an Ember Data record, including relationships?

此生再无相见时 提交于 2020-01-01 03:12:28

问题


I've figured out that I can clone an Ember Data record and copy its Attributes, but none of the belongsTo/hasMany relationships are cloned. Can I do this somehow if I don't know what relationships would be possible, going off of the relationships that exist?

For reference, here is what I've got that will clone an Ember Data record's attributes:

var attributeKeys = oldModel.get('constructor.attributes.keys.list');
var newRecord = this.get('store').createRecord(oldModel.constructor.typeKey);
newRecord.setProperties(oldModel.getProperties(attributeKeys));

回答1:


A few improvements to Daniel's answer that allows providing overrides, and clears the id for new records, to be safe. Also I prefer not to call save within the clone method, but leave it up to the caller.

DS.Model.reopen({
    clone: function(overrides) {
        var model = this,
            attrs = model.toJSON(),
            class_type = model.constructor;

        var root = Ember.String.decamelize(class_type.toString().split('.')[1]);

        /*
         * Need to replace the belongsTo association ( id ) with the
         * actual model instance.
         *
         * For example if belongsTo association is project, the
         * json value for project will be:  ( project: "project_id_1" )
         * and this needs to be converted to ( project: [projectInstance] )
         */
        this.eachRelationship(function(key, relationship) {
            if (relationship.kind == 'belongsTo') {
                attrs[key] = model.get(key);
            }
        });

        /*
         * Need to dissociate the new record from the old.
         */
        delete attrs.id;

        /*
         * Apply overrides if provided.
         */
        if (Ember.typeOf(overrides) === 'object') {
            Ember.setProperties(attrs, overrides);
        }

        return this.store.createRecord(root, attrs);
    }
});



回答2:


Here is a clone function that I use. Takes care of the belongs to associations.

 DS.Model.reopen({
   clone: function() {
    var model = this,
        attrs = model.toJSON(),
        class_type = model.constructor;

    var root = Ember.String.decamelize(class_type.toString().split('.')[1]);

    /**
     * Need to replace the belongsTo association ( id ) with the
     * actual model instance.
     *
     * For example if belongsTo association is project, the
     * json value for project will be:  ( project: "project_id_1" )
     * and this needs to be converted to ( project: [projectInstance] )
     *
     */
    this.eachRelationship(function(key, relationship){
      if (relationship.kind == 'belongsTo') {
        attrs[key] = model.get(key)
      }
    })

    return this.store.createRecord(root, attrs).save();
  }

})



回答3:


There's an addon called ember-cli-copyable that according to its description:

Deeply copies your records including their relations. The mixin is smart enough to resolve not loaded relations and is configurable to what should be shallow/deeply copied or excluded entirely.




回答4:


Here is the simple way to clone your Ember Model with relationships. working fine.

Create a Copyable mixin like,

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

Add the mixin in your model,

Note: If you want to clone your child model then, you need to include the mixin in child model as well

USAGE:

  1. With relationship : YOURMODEL.copy(true)

  2. Without relationship : YOURMODEL.copy()



来源:https://stackoverflow.com/questions/20007049/how-can-i-clone-an-ember-data-record-including-relationships

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!