Модель сэмпла Ember для новой записи
Я хочу сделать клон модели, которая в настоящее время редактируется.
Я нашел несколько способов, которые почти срабатывают. Но они не идеальны.
1) model.get('data.attributes')
получает все атрибуты, кроме отношений в форме camelCase, генерирует новый рекорд, но отношения, конечно, отсутствуют.
2) model.serialize()
генерирует объект JSON со всеми атрибутами, включая отношения. Но createRecord
не справится с этим, так как объект не является camelCased (атрибуты с символами подчеркивания типа first_name
не будут обрабатываться)
После создания моего клона я хочу transaction.createRecord(App.Document, myNewModelObject)
изменить/установить пару атрибутов и, наконец, commit()
. У кого-нибудь есть представление о том, как это сделать?
Ответы
Ответ 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-параллелизм, чтобы разрешить отмену задачи копирования