Ember.js - какой правильный шаблон контроллера/представления для создания новой модели
У меня есть приложение, которое на данный момент содержит представление объектов той же модели. Они извлекаются с сервера, зацикливаются и добавляются в контроллер списка с помощью метода add
<script>
App.Controllers.List = Em.ArrayProxy.create({
content: Ember.A([]),
add: function(obj){
this.pushObject(obj);
}
});
</script>
Теперь я работаю над тем, где пользователь создает новый объект, который (после прохождения проверки) будет добавлен в список, а также отправлен на сервер.
Я не могу найти ни одного примера для лучшего выбора для создания нового объекта через форму ввода. Я могу видеть несколько вариантов и полу-реализован несколько, но ничего не кажется правильным.
- Создайте представление с соответствующими элементами формы и методом для создания экземпляра модели с использованием различных свойств, полученных из элементов формы, используя .get()
- Создайте модель в содержимом представления и привяжите элементы формы к этому. Включите метод представления для добавления в массив контроллера/сохранения на сервере.
- Создайте модель, добавьте ее в массив контроллера и откройте ее для редактирования.
Я могу отбиваться от функциональности, которую хочу, но я бы предпочел, чтобы я знал о лучшей практике.
В настоящее время у меня есть что-то вроде этого (это вторая пуля в моем списке)
<script>
App.Views.ItemCreate = Em.View.extend({
content: App.Models.Item.create({}),
templateName: 'create',
createButton: function(){
var itemObj = this.get('content');
var item = {};
item.title = this.get('content').get('title');
$.ajax({
type: 'POST',
url: '/test/data.json',
data: item,
dataType: 'json',
success: function(responseData, textStatus, jqXHR) {
App.Controllers.List.add(itemObj);
}
});
}
});
</script>
<script type="text/x-handlebars" data-template-name="create">
{{view Em.TextField id="create-title" valueBinding="content.title"}}
<a href="#" {{action "createButton" }}>Create</a>
</script>
Любая помощь очень ценится
ПРИМЕЧАНИЯ
Я изменил правильный ответ на pangratz's. Хотя другие ответы напрямую ответили на мой вопрос, я считаю, что те, кто находит это через Google, должны ссылаться на ответ Pangratz, который представлен не только как хороший MVC, но и более Ember-y: o)
Ответы
Ответ 1
Общение с сервером - это то, что не должно быть сделано в представлении. Для этого необходим контроллер. Чтобы разделить различные части приложения дальше, я бы даже подумал о внедрении DataSource
, который обрабатывает запросы AJAX. Этот раскол делает ваше приложение более надежным и каждый компонент повторно используется. Конкретные соединения вида, контроллера и источника данных затем реализуются посредством привязок.
Рабочий процесс для вашего случая может быть следующим:
- В представлении отображается ваша форма редактирования, значения которой привязаны к контроллеру.
- Представление обрабатывает действие сохранения, которое сообщает контроллеру сохранить созданный объект
- Контроллер делегирует сохранение в DataSource, который затем, наконец, запускает запрос AJAX
- Контроллер уведомляется о сохранении объекта
Вы также должны посмотреть ember-data, который является хранилищем данных на стороне клиента и обрабатывает все шаблоны для вас. Также посмотрите Архитектура приложений Ember.js - данные и EmberJS: Хорошее разделение проблемы для моделей, магазинов, контроллеров, просмотров в довольно сложном приложении?
Вид:
App.View.ItemCreate = Ember.View.extend({
templateName: 'create',
createObject: function(evt) {
var object = this.get('content');
var controller = this.get('controller');
controller.createObject(object);
}
});
Контроллер:
App.Controllers.List = Ember.ArrayProxy.extend({
content: [],
createObject: function(hash) {
var dataSource = this.get('dataSource');
dataSource.createObject(hash, this, this.createdObject);
},
createdObject: function(object) {
this.pushObject(object);
}
});
DataSource:
App.DataSource = Ember.Object.extend({
createObject: function(hash, target, callback) {
Ember.$.ajax({
success: function(data) {
callback.apply(target, data);
}
});
}
});
Склеить все вместе:
App.dataSource = App.DataSource.create();
App.listController = App.Controllers.List.create({
dataSourceBinding: 'App.dataSource'
});
App.View.ItemCreate.create({
controllerBinding: 'App.listController'
}).append();
Ответ 2
Если вы хотите следовать строгой модели MVC, модель никогда не должна создаваться на представлении, а на контроллере. Ember все еще очень молод и по-прежнему не имеет определенных шаблонов, я бы сделал, чтобы ваша модель была настроена как содержимое представления (как вы уже сделали) со всеми входами, привязанными к различным атрибутам модели. Затем, когда кнопка нажата:
createButton: function(){
App.Controllers.List.create(this.get('content'));
}
На контроллере:
create: function(model) {
if model.valid() { //validates the model
model.save({
onSuccess: function(response) { // callback
var item = App.Models.Item.create(response.item)
App.controllers.List.add(item)
}
})
}
И, наконец, модель:
save: function(options) {
$.ajax({
type: 'POST',
url: '/test/data.json',
data: item,
dataType: 'json',
success: options.onsuccess
});
}
Таким образом, другие js-фреймворки ожидают, что вы будете работать. Он чувствует себя немного более многословным и сложным, но он держит вещи на месте.