Непостоянные атрибуты в EmberJS
Кто-нибудь знает способ указать для Ember model
атрибут, который не сохранился?
По сути, мы загружаем некоторые метаданные, относящиеся к каждой модели, и отправляем эти данные в Ember через RESTAdapter
в модели. Эти метаданные можно изменить в нашем приложении, но это делается с помощью вызова AJAX. Как только вызов завершится успешно, я хочу иметь возможность обновить это значение в модели, при этом Эмбер не сует свой нос в этом деле, изменив модель на uncommitted
и делать то, что он делает с transactions
за кулисами.
У меня также есть проблема, что это метаданные, которые не являются данными из model
запись в базе данных, переданная RESTAdapter
обратно на сервер, который не ожидает этих значений. Я использую бэкэнд RoR, поэтому сервер выдает ошибку при попытке массово назначить защищенные атрибуты, которые вообще не должны быть атрибутами. Я знаю, что могу очистить данные, полученные на сервере, но я бы предпочел, чтобы клиент мог различать постоянные данные и вспомогательные данные.
Итак, к первоначальному вопросу: есть ли альтернатива Ember-Data? DS.attr('...')
который будет указывать непостоянный атрибут?
4 ответа
После слияния этого 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
установленный флаг пропускает свойство.
Я надеюсь, что этот механизм работает для вашего случая использования.
Другие ответы на этот вопрос работают с версиями данных 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})
});
Эти атрибуты не будут отправлены на сервер при сохранении записей.
После этого ответа, чтобы предотвратить сериализацию поля, переопределите сериализатор по умолчанию для вашей модели:
В app/serializers/person.js
:
export default DS.JSONSerializer.extend({
attrs: {
admin: { serialize: false }
}
});
Смотрите здесь для источника PR. Это решение работает в Ember Data 2 и должно работать в более старых версиях.
Обновить
Этот ответ, скорее всего, устарел с текущими выпусками Ember Data. Я не буду ничего использовать в своем ответе.
Я отвечаю на этот вопрос для справки, и потому что ваш комментарий указал, что запись остается isDirty
, но здесь мое решение для непостоянных, не грязных атрибутов только для чтения.
Переопределение addAtributes
метод в вашем сериализаторе мешает 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
Эта настройка работает для меня.