【问题标题】:Using components instead controllers in EmberJS v2在 EmberJS v2 中使用组件而不是控制器
【发布时间】:2016-03-29 03:40:04
【问题描述】:

我是 EmberJS 的初学者。我为学习 Ember 制作了 todomvc for ember v2

我的实现在没有控制器的情况下工作。我使用组件而不是控制器。因为在documentation我看到了

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

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

这是我的 todolist 的 todo item 组件的模板 应用程序/模板/组件/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() 方法中的 todos 路由中处理。我在这个方法中有 todo.save()。

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

我有以下动作链

组件模板->组件js->路由

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

我还想看看你们的 cmets 关于我的解决方案(组件而不是控制器)或我的代码的任何部分。

谢谢朋友们!

【问题讨论】:

  • 如果您想查看您的代码,codereview.stackexchange.com 可能会更好,尤其是考虑到您的代码正在运行。
  • 不幸的是,codereview 网站有 8 个 ember.js 标签的关注者。 Stackoverflow 有 2.8K 的关注者关注这个标签。

标签: javascript ember.js


【解决方案1】:

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

【讨论】:

  • 嗨!我认为 isEditing 对于模型来说是个坏地方,因为这个属性用于显示待办事项的 GUI 状态。在模型中,我们必须具有将存储到服务器的属性。
猜你喜欢
  • 2015-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-01
  • 2013-12-15
  • 2014-11-24
相关资源
最近更新 更多