Изучая документацию EmberJs и различные примеры становится понятно, что существующее в данный момент приложение todomvc (ember реализация), на данный момент, сильно устарело. В процессе развития Ember его разработчики непрерывно переосмысливают опыт и используют все новые подходы для построения приложения. Поэтому от версии к версии многое меняется. Под вторую версию EmberJs пока что нет официальной реализации todomvc.
Я попытался понять на сколько реализация для версии 2 будет отчаться от реализации для версии 1.10. Начал с чтения документации и первое, что бросилось в глаза – информация о контроллерах:
Controllers are very much like components, so much so that in future versions of Ember, controllers will be replaced entirely with components.
Выходит, что контроллеры отмирают. И тогда я реализовал свою версию todomvc, но без контроллеров и без тех устаревших приемов, которые в версии 2 не работаю.
Но по завершению работы у меня остались вопросы, на которые я пока не нашел исчерпывающего ответа.
Вот код шаблона для компонента пункта todo-листа app/templates/components/todo-item.hbs:
<li class="{{if isCompleted 'completed'}} {{if isEditing 'editing'}}">
{{#if isEditing}}
{{input-focused class="edit" value=item.title focus-out="acceptChanges" insert-newline="acceptChanges"}}
{{else}}
{{input type="checkbox" checked=isCompleted class="toggle"}}
<label {{action "editTodo" on="doubleClick"}}>{{item.title}}</label>
<button {{action "removeTodo"}} class="destroy"></button>
{{/if}}
</li>
Здесь есть события acceptChanges и removeTod. И в Js-части компонента имеются их обработчики:
import Ember from 'ember';
export default Ember.Component.extend({
updateTodoAction: 'updateTodo',
deleteTodoAction: 'deleteTodo',
isEditing: false,
// some lines removed for brevity
actions: {
editTodo: function() {
this.set('isEditing', true);
},
acceptChanges: function() {
this.set('isEditing', false);
this.sendAction('updateTodoAction', this.get('item'), this.get('item.title'));
},
removeTodo: function () {
this.sendAction('deleteTodoAction', this.get('item'));
}
}
});
В js-коде компонента я не работаю с хранилищем (storage). Я вызываю this.sendAction(), и мой маршрут (route) обрабатывает это событие. Маршрут todos работает с хранилищем. Вот код:
// app/routes/todos.js
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.store.findAll('todo');
},
actions: {
// some lines removed from here for brevity
updateTodo: function(todo, title) {
if (Ember.isEmpty(title)) {
this.send('deleteTodo', todo);
} else {
todo.save();
}
},
deleteTodo: function(todo) {
todo.deleteRecord();
todo.save();
},
// some lines removed from here for brevity
}
});
Когда пользователь кликает по кнопки удаления, то генерируется событие (действие, action) removeTodo и оно обрабатывается в removeTodo() в Js-части компонента. Где вызывается метод this.sendAction(‘deleteTodoAction’ … ), который генерирует событие (action) deleteTodo. Это событие будет обработано в маршруте todos в методе deleteTodo(). Где вызывается todo.save().
Событие acceptChanges работает точно также как и removeTodo, но только оно устанавливает свойство isEditing = false перед вызовом this.sendAction.
Итак я имею следующую цепочку обработки действия:
component template -> component js -> route
Я думаю, что для deleteTodo() будет лучше, если исключить js-часть компонента. Но как? В updateTodo() мне нужна js-часть компонента, так как я устанавливаю новое значение для свойства isEditing. Но для вызова маршрута мне нужно объявить свойство updateTodoAction для компонента todo-item. В js-коде или же в шаблоне. Так работает sendAction.
И это кажется мне некрасивым. Можно ли мне работать без свойства updateTodoAction? Каким образом?
Как видите здесь есть лишнее звено. Но у меня не получается от него избавиться. Очень хотелось бы увидеть чьи-либо комментарии по этому поводу. А так же любые комментарии по моей реализации todomvc для EmberJs 2.
Спасибо всем!