Подтвердить что ты не робот

Модель сэмпла Ember для новой записи

Я хочу сделать клон модели, которая в настоящее время редактируется.

Я нашел несколько способов, которые почти срабатывают. Но они не идеальны.

1) model.get('data.attributes') получает все атрибуты, кроме отношений в форме camelCase, генерирует новый рекорд, но отношения, конечно, отсутствуют.

2) model.serialize() генерирует объект JSON со всеми атрибутами, включая отношения. Но createRecord не справится с этим, так как объект не является camelCased (атрибуты с символами подчеркивания типа first_name не будут обрабатываться)

После создания моего клона я хочу transaction.createRecord(App.Document, myNewModelObject) изменить/установить пару атрибутов и, наконец, commit(). У кого-нибудь есть представление о том, как это сделать?

4b9b3361

Ответ 1

Здесь обновленный ответ, он по-прежнему не обрабатывает отношения 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

Теперь у нас есть дополнение для копирования моделей ember-cli-copyable

С этим дополнением, просто добавьте Copyable в целевую модель, которую нужно скопировать, и используйте метод копирования.

Пример с сайта дополнения

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) 

});

Ответ 3

Как насчет использования метода toJSON() вместо serialize(), подобного этому

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

Ответ 4

Самый простой способ найти:

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

Ответ 5

Вот простой способ клонирования вашей модели Ember с отношениями. отлично работает.

Создайте способ копирования, например,

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 в дочернюю модель

ПРИМЕНЕНИЕ:

  • С отношением: YOURMODEL.copy(true)
  • Без отношений: YOURMODEL.copy()

Ответ 6

Это также решит мою проблему

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

Ответ 7

Вы можете использовать https://github.com/offirgolan/ember-data-copyable. Уже давно пользуюсь этим пакетом, и он очень надежный. Некоторые из его особенностей:

  • Мелкая и глубокая копия Ember Data модель

  • Неглубокие и глубокие отношения модели копирования

  • Обрабатывает циклические отношения

  • Обрабатывает пользовательские преобразования для создания истинных копий

  • Перезаписывать, игнорировать атрибуты и копировать объекты по ссылке

  • Интеллектуальный сбой и очистка

  • Использует ember-параллелизм, чтобы разрешить отмену задачи копирования