Ember克隆模型用于新记录

时间:2013-02-16 16:23:48

标签: ember.js

我想要复制当前正在编辑的模型。

我发现了几种几乎可以工作的方法。但两者都不完美。

1)model.get('data.attributes')获取除camelCase形式的关系之外的所有属性,生成新的记录,但当然缺少关系。

2)model.serialize()生成一个JSON对象,其中包含所有属性,包括关系。但是createRecord将无法很好地处理它,因为该对象不是camelCased(不会处理带有first_name等下划线的属性

创建克隆后,我希望transaction.createRecord(App.Document, myNewModelObject)更改/设置一些属性,最后commit()。任何人都对如何做到这一点有所了解?

6 个答案:

答案 0 :(得分:2)

如何使用toJSON()方法而不是像这样序列化()

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

答案 1 :(得分:0)

这是一个更新的答案,它仍然无法处理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));
      }
    });
  });
}

以下是我如何使用它:

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

答案 2 :(得分:0)

我发现最简单的方式:

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

答案 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()

答案 4 :(得分:0)

这也将解决我的问题

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

答案 5 :(得分:0)

您可以使用https://github.com/offirgolan/ember-data-copyable。现在已经使用此程序包一段时间了,它非常可靠。它的一些功能:

  • 浅层和深层复制Ember Data模型

  • 浅层和深层复制模型关系

  • 处理周期性关系

  • 处理自定义转换以创建真实副本

  • 覆盖,忽略属性并通过引用复制对象

  • 智能故障和清除

  • 使用ember-concurrency来取消复制任务