如何克隆Ember数据记录,包括关系?

时间:2013-11-15 17:28:01

标签: ember.js ember-data

我已经发现我可以克隆Ember数据记录并复制其属性,但没有克隆belongsTo / hasMany关系。如果我不知道哪种关系可能会脱离现有的关系,我能以某种方式这样做吗?

作为参考,以下是我将克隆Ember数据记录属性的内容:

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

4 个答案:

答案 0 :(得分:8)

丹尼尔answer的一些改进,允许提供覆盖,并清除新记录的ID,以确保安全。此外,我不想在克隆方法中调用save,而是将其留给调用者。

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

答案 1 :(得分:4)

这是我使用的克隆功能。照顾属于协会。

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

})

答案 2 :(得分:0)

根据其描述,有一个名为ember-cli-copyable的插件:

  

深入复制您的记录,包括他们的关系。 mixin足够聪明,可以解决未加载的关系,并且可以配置为应该被浅/深度复制或完全排除。

答案 3 :(得分:0)

以下是使用关系克隆 Ember模型的简单方法。 工作正常。

创建一个可复制的mixin,如

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

在模型中添加mixin,

注意:如果您想要克隆您的子模型,那么您还需要在子模型中包含mixin

用法:

  1. 有关系:YOURMODEL.copy(true)

  2. 没有关系:YOURMODEL.copy()