#ember.js
#ember.js
Вопрос:
У меня есть форма, в которой посетители могут оставить комментарий с типичным флажком «Я принимаю ToS» и ссылкой. Ссылка переходит на новый маршрут с текстом ToS.
Я создаю свою запись комментария, когда маршрут с формой загружен. Я делаю это, чтобы мой шаблон мог загружать правильные настройки по умолчанию (например, есть переключатель gender, для которого установлено правильное значение благодаря Ember data attrs).
App.CommentRoute = Ember.Route.extend({
model: function() {
return this.store.createRecord('comment');
}
actions: {
create: function(comment) {
comment.save();
}
}
});
Модель комментариев:
App.Comment = DS.Model.extend({
body: DS.attr("string"),
gender: DS.attr("string", {defaultValue: "M"}),
});
И шаблон:
<form {{action "create" this on="submit"}}>
...
</form>
Теперь, когда пользователи нажимают кнопку «Назад» на странице ToS, все поля формы очищаются при загрузке новой модели. Я действительно хочу такого поведения после сохранения формы или при ее перезагрузке, но, очевидно, не при использовании кнопки «Назад». Я обошел это, сохранив глобальное состояние, но чувствую, что должен быть лучший способ. Какие-нибудь советы?
Ответ №1:
Существует множество способов сделать это, поэтому я ожидаю несколько других ответов. Я лично не стал бы начинать маршрут с новой записи…
Обычно я резервирую это соглашение об именовании ( Comment
) для маршрута GET
с определенным идентификатором модели… В идеале все это должно быть на вызываемом маршруте App.CommentNewRoute
. Но да, все, что вам подходит.
Вот один из способов, которым вы можете это сделать:
App.CommentRoute = Ember.Route.extend({
model: function() {
if(Ember.isEmpty(this.modelFor('comment'))){
return this.store.createRecord('comment');
} else {
return this.modelFor('comment');
}
}
actions: {
create: function(comment) {
comment.save();
this.set('model', this.store.createRecord('comment'));
}
}
});
Кажется немного неуклюжим, но это должно подтолкнуть вас к вашему текущему подходу. Вы в основном проверяете, существует ли модель. Если это произойдет, вы просто возвращаете эту модель, поскольку она могла измениться.
Когда вы создаете комментарий, он сохраняет, а затем сбрасывает модель с новой записью.
Удачи!
Ответ №2:
Всякий раз, когда у меня есть какой-то маршрут «формы» (новый, редактирование и т. Д.) Я использую следующее соглашение об именовании: App.CommentsNewRoute
и App.CommentEditRoute
. Это дает вам возможность разбивать имя маршрута и иметь свойства в контроллере для отображения и скрытия различных входных данных в зависимости от того, редактирует или создает что-то пользователь.
Что касается маршрутов…
Новый маршрут (комментарии / новый):
App.CommentsNewRoute = Em.Route.extend({
actions: {
willTransition: function(transition) {
var model = this.get('controller.content');
if (model.get('isDirty')) {
model.deleteRecord();
}
}
},
model: function() {
return this.store.createRecord('comment');
},
});
Редактировать маршрут (комментарий/:comment_id/edit):
App.CommentEditRoute = Em.Route.extend({
actions: {
willTransition: function(transition) {
var model = this.get('controller.content');
if (model.get('isDirty')) {
model.rollback();
}
}
},
});
Маршрутизатор:
App.Router.map(function() {
this.resource('comments', function() {
this.route('new');
this.resource('comment', { path: '/:comment_id' }, function() {
this.route('show', { path: '/' });
this.route('edit');
});
});
});
Каждый контроллер и представление формы имеют mixin, который обрабатывает события отправки, отмены, уничтожения, проверки и ошибки сервера, а также имеет некоторые вычисляемые свойства (например editing: true
, new: false
).
Ответ №3:
Я вижу проблему с сохранением (или созданием или удалением) моделей в методе willtransition или в методе действия контроллера: сохранение является асинхронным, и мы не можем естественным образом управлять асинхронностью (состояниями ошибок и загрузки) с помощью ember. Итак, имхо, такого рода операции должны проходить через хуки boforeModel / model / afterModel. Я предлагаю:
App.CommentsNewRoute = Em.Route.extend({
actions: {
clickSaveButton: function(transition) {
var model = this.controller.get('model');
if (model.get('isDirty') amp;amp; !model.get('isEmpty')) {
this.refresh(); // to call model hook
}
}
},
model: function() {
if(this.controller){
var model = this.controller.get('model');
if(model amp;amp; model.get('isDirty')){
return this.model.save();// return promise as it shold be
}
}
return this.store.createRecord('comment');
},
});
аналогично для удаления и редактирования записей