Todomvc на Ember2 без контроллеров

Изучая документацию 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.

Спасибо всем!

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *