Непрерывные атрибуты в EmberJS
Кто-нибудь знает способ указать для Ember model
атрибут, который не сохраняется?
В основном мы загружаем некоторые метаданные, относящиеся к каждой модели, и отправляем эти данные в Ember через RESTAdapter
в рамках модели. Эти метаданные можно изменить в нашем приложении, но это делается с помощью вызова AJAX. Как только вызов преуспеет, я хочу обновить это значение в модели без использования Ember в этом деле, изменив модель на uncommitted
и сделав все, что бы она делала с transactions
за кулисами.
У меня также есть проблема, что эти метаданные, которые не являются данными из записи базы данных model
, передаются RESTAdapter
обратно на сервер, что не ожидает этих значений. Я использую бэкэнд RoR, поэтому на сервере возникают ошибки, пытаясь назначить защищенные атрибуты, которые не предназначены для атрибутов вообще. Я знаю, что могу очистить данные, полученные на сервере, но я бы предпочел, чтобы клиент мог различать постоянные данные и вспомогательные данные.
Итак, к исходному вопросу: есть ли какая-либо альтернатива Ember-Data DS.attr('...')
, которая будет указывать непостоянный атрибут?
Ответы
Ответ 1
Когда этот PR будет объединен, можно будет пометить свойства как readOnly
. Но до тех пор есть некоторые обходные пути к этому, например. переопределяя ваш метод addAttributes
в адаптере и обрабатывая ваши специальные свойства, вот пример, как это могло бы выглядеть:
Определите модель, добавив новую опцию readOnly
:
App.MyModel = DS.Model.extend({
myMetaProperty: DS.attr('metaProperty', {readOnly: true})
});
а затем на адаптере:
App.Serializer = DS.RESTSerializer.extend({
addAttributes: function(data, record) {
record.eachAttribute(function(name, attribute) {
if (!attribute.options.readOnly) {
this._addAttribute(data, record, name, attribute.type);
}
}, this);
}
});
то, что это делает, - это цикл над атрибутами вашей модели, и когда он находит атрибут с флагом readOnly
, он пропускает свойство.
Я надеюсь, что этот механизм работает для вашего использования.
Ответ 2
Другие ответы на этот вопрос работают с версиями данных Ember до 0,13 и больше не работают.
Для Ember data 1.0 beta 3 вы можете:
App.ApplicationSerializer = DS.RESTSerializer.extend({
serializeAttribute: function(record, json, key, attribute) {
if (attribute.options.transient) {
return;
}
return this._super(record, json, key, attribute);
}
});
Теперь вы можете использовать переходные атрибуты:
App.User = DS.Model.extend({
name: DS.attr('string', {transient: true})
});
Эти атрибуты не будут отправляться на сервер при сохранении записей.
Ответ 3
Следуя этому answer, чтобы предотвратить сериализацию поля, переопределите сериализатор по умолчанию для вашей модели:
В app/serializers/person.js
:
export default DS.JSONSerializer.extend({
attrs: {
admin: { serialize: false }
}
});
Смотрите здесь для источника PR. Это решение работает в Ember Data 2 и должно работать и в более старых версиях.
Ответ 4
Update
Этот ответ, скорее всего, устарел с текущими выпусками Ember Data. Я бы ничего не использовал в своем ответе.
Я отвечаю на этот вопрос для справки, и потому, что в вашем комментарии указано, что запись остается isDirty
, но вот мое решение для только для чтения, non-persistent strong > , не-грязные.
Переопределение метода addAtributes
в вашем Serializer предотвращает отправку атрибутов readOnly
на сервер, что, вероятно, именно то, что вы хотите, но вам нужно расширить (или reopen
) ваш адаптер, чтобы переопределить dirtyRecordsForAttributeChange
, чтобы предотвратить загрязнение записи:
App.CustomAdapter = DS.RESTAdapter.extend({
dirtyRecordsForAttributeChange: function(dirtySet, record, attrName, newValue, oldValue) {
meta = record.constructor.metaForProperty(attrName);
if (meta && meta.options.readOnly) { return; }
this._super.apply(this, arguments);
};
});
Затем вы можете использовать атрибуты readOnly
, например:
App.User = DS.Model.extend({
name: DS.attr('string', {readOnly: true})
});
user = App.User.find(1); # => {id: 1, name: 'John Doe'}
user.set('name', 'Jane Doe'); #
user.get('isDirty') # => false
Эта настройка работает для меня.