Подтвердить что ты не робот

Создание записи с данными Ember.js & Ember-data & Rails и обработкой списков записей

Я создаю приложение с макетом, как показано ниже.

preview

Я хочу создать новое сообщение, поэтому я нажал кнопку "Создать сообщение", и он перешел на маршрут "сообщения/новые".

Мои сообщенияNewRoute, как показано ниже (я следовал описанному методу здесь)

 App.PostsNewRoute = Ember.Route.extend({
     model: function() {

           // create a separate transaction, 

           var transaction = this.get('store').transaction();

           // create a record using that transaction

           var post = transaction.createRecord(App.Post, {
                title: 'default placeholder title',
                body: 'default placeholder body'
           });

          return post;
     } 
 });

Он немедленно создает новую запись, обновляет список сообщений и отображает формы для нового сообщения.

preview
(источник: sunshineunderground.kr)

Теперь у меня две проблемы.

Одним из них является порядок списка сообщений.

Я ожидал, что новое сообщение будет в верхней части списка, но оно будет в нижней части списка.

Я использую рельсы в качестве моего бэкэнда, и я установил порядок модели Post на

 default_scope order('created_at DESC')

такая старая запись находится ниже существующих записей. но недавно созданный не является. (который еще не предназначен для бэкэнда)

Другой - Когда я нажимаю на созданную запись в списке

Я могу нажать на свой недавно созданный пост в списке постов. и он взял меня на страницу поста с URL

 /posts/null

и это очень странное поведение, которое я должен предотвратить.

Я думаю, что будет два решения.

  1. Когда я нажимаю "кнопку нового сообщения", немедленно создаю запись и фиксирую на сервере, а когда сервер успешно сохранил мою новую запись, обновите список сообщений и войдите в режим редактирования вновь созданного сообщения.

  2. или изначально установите для модели маршрута значение null и создайте запись, когда я нажму кнопку "отправить" в PostsNewView.

  3. или показывать только те сообщения, атрибут которых

        'isNew' = false, 'isDirty' = false, 
    

в списке..

Но, к сожалению, я не знаю, с чего начать...

для решения 1 я полностью теряюсь.

для решения 2 я не знаю, как связать данные в формах ввода с еще не существующей моделью.

для решения 3 я полностью теряюсь.

Пожалуйста, помогите мне! какой будет angularьный путь?

(Я слышал, что Ember намеревается использовать одно и то же решение для каждого разработчика)

Обновление

Сейчас я использую решение 3 и все еще имею проблему с заказом. Вот мой код шаблона сообщений.

    <div class="tools">
        {{#linkTo posts.new }}new post button{{/linkTo}}
    </div>
    <ul class="post-list">
        {{#each post in filteredContent}}
        <li>
            {{#linkTo post post }}
                <h3>{{ post.title }}</h3>
                <p class="date">2013/01/13</p>
                <div class="arrow"></div>
            {{/linkTo}}
        </li>
        {{/each}}
    </ul>
    {{outlet}}

Обновление

Я решил эту проблему, отфильтровав "aniContent ", а не" content "

 App.PostsController = Ember.ArrayController.extend({
   sortProperties: ['id'],
   sortAscending: false,
   filteredContent: (function() {

     var content = this.get('arrangedContent');

     return content.filter(function(item, index) {
       return !(item.get('isDirty'));
     });
   }).property('[email protected]')

 });
4b9b3361

Ответ 1

Мы используем вариацию решения 3 в нескольких местах нашего приложения. IMHO это самый чистый из 3, так как вам не нужно беспокоиться о настройке/разрыве на стороне сервера. Вот как мы его реализуем:

App.PostsController = Ember.ArrayController.extend({
  sortProperties: ['id'],
  sortAscending: true,
  filteredContent: (function() {
    return this.get('content').filter(function(item, index) {
      return !(item.get('isDirty'));
    });
  }).property('[email protected]')
});

Затем в вашем шаблоне Posts вы выполняете loop.filteredContent вместо control.content.

Для решения 1 существует много возможностей. Вы можете определить следующее событие:

  createPost: function() {
    var post,
      _this = this;
    post = App.Post.createRecord({});
    post.one('didCreate', function() {
      return Ember.run.next(_this, function() {
        return this.transitionTo("posts.edit", post);
      });
    });
    return post.get("store").commit();
  }

Создает сообщение, затем устанавливает обещание, которое будет выполнено после срабатывания "didCreate" в сообщении. Это обещание переходит на пост-маршрут только после того, как оно вернулось с сервера, поэтому оно будет иметь правильный идентификатор.

Ответ 2

Действительно, очень приятно писать. спасибо для этого.

Разве ваш filteredContent не должен использовать состояние isNew i.o. isDirty, в противном случае Post, который редактируется, не будет виден. В любом случае свойство filteredContent не работает в моем случае. Я также заметил, что, поскольку я использую изображение как часть каждого элемента, все изображения будут обновляться при изменении filteredContent. Это означает, что я вижу запрос для каждого изображения.

Я использую несколько иной подход. Я просматриваю содержимое и решаю, показывать или не показывать Опубликовать в шаблоне:

# posts.handlebars
<ul class='posts'>
  {{#each controller}}
    {{#unless isNew}}
      <li>
        <h3>{{#linkTo post this}}{{title}}{{/linkTo}}</h3>
        <img {{bindAttr src="imageUrl"}}/>
        <a {{action deletePost}} class="delete-post tiny button">Delete</a>
      </li>
    {{/unless}}
  {{/each}}
</ul>

После сохранения будет отображаться объект Опубликовать. URL-адрес в теге H3 также содержит идентификатор вновь созданного объекта i.o. сообщения/нуль.

Еще одна вещь, которую я заметил в вашем вопросе: вместо того, чтобы передавать значения по умолчанию для createRecord, вы можете использовать свойство defaultValues ​​для самой модели:

Итак, вместо:

# App.PostsNewRoute
var post = transaction.createRecord(App.Post, {
            title: 'default placeholder title',
            body: 'default placeholder body'
       });

вы можете сделать это:

# App.Post
App.Post = DS.Model.extend({
  title: DS.attr('string', {
    defaultValue: "default placeholder title"
  }),
  body: DS.attr('string', {
    defaultValue: "default placeholder body"
  })
});

# App.PostsNewRoute
var post = transaction.createRecord(App.Post);

Ответ 3

На самом деле я написал функцию, чтобы отменить массив содержимого a назад:

http://andymatthews.net/read/2012/03/20/Reversing-the-output-of-an-Ember.js-content-array

Это довольно старая статья, почти год назад, поэтому она, вероятно, не будет работать так, как есть, но структура существует...

Вы можете увидеть это в действии в этом мини-приложении, которое я написал:

http://andymatthews.net/code/emberTweets/

Искать пользователей в поле ввода вверху и смотреть на левую сторону, как они появляются в порядке от самых старых до самых старых (вместо самых старых и новейших).