Шаблон Ember для «новых» маршрутов

#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');
    },
});
 

аналогично для удаления и редактирования записей