Создание записи с данными 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
и это очень странное поведение, которое я должен предотвратить.
Я думаю, что будет два решения.
Когда я нажимаю "кнопку нового сообщения", немедленно создаю запись и фиксирую на сервере, а когда сервер успешно сохранил мою новую запись, обновите список сообщений и войдите в режим редактирования вновь созданного сообщения.
или изначально установите для модели маршрута значение null и создайте запись, когда я нажму кнопку "отправить" в PostsNewView.
или показывать только те сообщения, атрибут которых
'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]')
});
Ответы
Ответ 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/
Искать пользователей в поле ввода вверху и смотреть на левую сторону, как они появляются в порядке от самых старых до самых старых (вместо самых старых и новейших).