在EmberJS v2中使用组件代替控制器

时间:2015-12-22 19:36:25

标签: javascript ember.js

我是EmberJS的初学者。为了学习恩伯,我已经todomvc for ember v2了。

我的实施没有控制器。我使用组件代替控制器。因为在documentation我看到了

  

控制器与组件非常相似,以至于在未来的Ember版本中,控制器将完全由组件替换。

但我认为这是一个丑陋的解决方案。现在我将解释原因。

这是我的todolist的todo项目组件的模板 应用程序/模板/组件/ 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和removeTodo事件。 在js组件的一部分我有处理程序:

//app/components/todo-item.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代码中,我不使用存储。我发送this.sendAction(),我的路线将处理它。并且todos-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
    }
});

当用户点击删除按钮时,它会生成removeTodo动作,它将在组件的js部分的removeTodo()中处理。 然后removeTodo()函数调用this.sendAction('deleteTodoAction'...),它会生成deleteTodo动作。此操作将在deleteTodo()方法中的待办事项路由中处理。我在这个方法中有todo.save()。

acceptChanges操作与removeTodo非常相似,但在调用this.sendAction之前设置属性isEditing = false。

我有以下行动链

组件模板 - &gt;组件js - &gt;路线

我认为deleteTodo()会更好地排除组件js部分。但是怎么样? 在updateTodo()中我需要组件js part,因为我为isEditing属性设置了值。但是对于调用路由我需要updateTodoAction属性。这对我来说很难看。没有updateTodoAction属性可以工作吗?怎么样?

此外,我想看到您对我的解决方案(组件代替控制器)或我的代码的任何部分的任何意见。

谢谢你,朋友们!

1 个答案:

答案 0 :(得分:0)

您可以将属性设置为模型而不是组件。例如,set item.isEditing而不是isEditing。在您的路线操作中,您拥有该项目并可以切换isEditing属性。在模板中,将您的if更改为{{if item.isEditing ...