Операции с данными Ember-данных и повторная отправка форм
Я использую ember (+ data) и создал простую форму регистрации, но мне трудно получить форму (и транзакцию с данными ember-data), чтобы корректно работать после ошибки проверки на стороне сервера.
Я следую https://github.com/dgeb/ember_data_example в качестве руководства по использованию транзакций, и он в основном работает для Happy Path, но после ошибка проверки на стороне сервера, я не могу получить данные ember для повторной отправки запроса API, когда я нажимаю "Отправить".
Я немного искал, и я думаю, что мне не хватает какого-то шага, связанного с сбросом транзакции после того, как модель станет недействительной или что-то в этом роде...
Github и приложение
Вы можете попробовать приложение и воспроизвести проблему на http://emb.herokuapp.com/
Вы также можете изучить полный исходный код https://github.com/justinfaulkner/ember-data-resubmit
Репро
Вы можете вызвать ложную ошибку на стороне сервера, заполнив форму в моем приложении, используя адрес электронной почты на @example.com. Rails API ответит 422 и объект ошибок, привязанный к полю username/email.
Поле должно быть выделено красным цветом с ошибкой - измените адрес электронной почты на то, что должно быть действительным, и нажмите "Отправить еще раз". С инструментами разработчика, открытыми в chrome, я не вижу ember-данных, отправляющих HTTP-запрос с кликом (но console.log в контроллере указывает, что клик действительно принимается).
Что должно произойти
После изменения поля с ошибкой, ember-data (я думаю) изменяет модель от invalid
до uncommitted
, так что она будет отправлена при следующем вызове commit
. Когда я нажимаю "Отправить", данные ember-data должны отправлять HTTP-запрос на мой api, а ember должен перейти к "Congrats!". стр.
Вместо этого, однако, форма просто сидит там. Нет HTTP-запроса. Нет перехода на "Congrats!".
Вот скриншот после того, как я нажал Отправить несколько (18) раз после обновления входов:
![Submit button click received, but no http request]()
Отрывки
Вот некоторые фрагменты моего приложения ember:
IndexRoute
Мой маршрут, который использует startEditing
, например, ember_data_example:
App.IndexRoute = Ember.Route.extend({
model: function() {
return null;
},
setupController: function(controller) {
controller.startEditing();
},
deactivate: function() {
this.controllerFor('index').stopEditing();
}
});
IndexController
Мой IndexController
моделируется после ember_data_example ContactsNewController
App.IndexController = Ember.ObjectController.extend({
startEditing: function() {
this.transaction = this.get('store').transaction();
this.set('content', this.transaction.createRecord(App.User));
},
submit: function(user){
console.log("submitting!");
this.transaction.commit();
this.transaction = null;
},
_transitionOnSuccess: function(stuff) {
if (this.get('content.id') && this.get('content.id').length > 0) {
console.log("_transitionOnSuccess");
this.transitionToRoute('success');
}
}.observes('content.id'),
stopEditing: function() {
if (this.transaction) {
this.transaction.rollback();
this.transaction = null;
}
}
});
User
Вот моя модель. Я использую ember-validations.
App.User = DS.Model.extend(Ember.Validations.Mixin);
App.User.reopen({
username: DS.attr('string'),
password: DS.attr('string'),
profile: DS.belongsTo('App.Profile'),
validations: {
username: {
presence: true
},
password: {
presence: true,
length: { minimum: 6 }
}
}
});
index.hbs
А вот форма из моего шаблона руля. Я использую ember-easyForm.
{{#formFor controller}}
<div class="row">
<div class="large-12 columns">
{{input username placeholder="Email address"}}
</div>
</div>
<div class="row">
<div class="large-12 columns">
{{input password placeholder="Password"}}
</div>
</div>
{{submit "Sign Up" class="button"}}
{{/formFor}}
В случае, если авторы библиотеки видят этот пост, я сделал пару локальных изменений в копии приложения ember-easyForm и ember-валидации в этой фиксации: https://github.com/justinfaulkner/dockyard-example/commit/f618b0e4fb72314d56bb3a9d95e1325925ba6ad0. Я не думаю, что мои изменения вызывают мою проблему.
wasInvalid и rollback?
Я столкнулся с похожим вопросом: Ember Data и грязные записи, но когда я добавил User.becameInvalid
для откат транзакции, это вызвало форму пустым при попытке повторно отправить (и до сих пор не удалось получить данные ember-данных, повторно отправить HTTP-запрос).
Спасибо!
Я уверен, что я плохо слежу за ember_data_example
(или не могу продлить его до моего использования), или я делаю какую-то простую ошибку где-то...
Спасибо заранее.
Редактировать Апр 5
До сих пор я могу найти как минимум две основные проблемы:
-
this.transaction = null;
Нужно ли мне это? Что мне делать вместо этого?
- Я попробовал удалить
this.transaction = null;
, а ember-data пытается на самом деле зафиксировать сейчас (но все равно не отправит запрос ajax). Теперь, когда я ввожу недопустимое поле, я вижу, что данные ember-data пытаются обновить запись до uncommitted
/created
... , но она делает это в другой транзакции.
Я переместил ветвь no-null
на репо, у которого есть некоторая console.log
в ember-data, которая выводит на экран идентификатор транзакции... здесь снимок моей консоли:
![different transaction]()
recordBecameDirty
вызывается при вводе в поле. Ember-data обновляет запись, чтобы быть готовой к повторной передаче. Но он делает это в какой-то другой транзакции (458)
Но моя кнопка отправки привязана к исходной транзакции (316), и нет записей, готовых к фиксации в этой транзакции.... hmm....
Ответы
Ответ 1
Это известная проблема с данными ember.
См.: https://github.com/emberjs/data/pull/539
Простое изменение Ember Data в том, что commit
https://github.com/Cyril-sf/data/commit/fe9c63beb02e9f16051e59a9f7c0a918152a0231
должен решить вашу проблему.