在Ember.js中处理事件的最佳方法是什么?

Tes*_*est 11 ember.js

我开始学习Ember并且不清楚处理事件的最佳,最可接受甚至是预期的方法是什么.是否可以在click函数事件参数中检查目标,是否应该为需要除{{action}}以外的事件的每个项目创建一个新视图,或者完全不同的事情?

Pan*_*agi 8

IMO你应该尽可能使用{{action}}帮助器.如果要在模板中的标记上附加事件,请使用{{action}}; 无需制作新视图:

<a {{action showPosts href=true}}>All Posts</a>

<form {{action validate target="controller"}}>
  // ...
</form>
Run Code Online (Sandbox Code Playgroud)

上述情况的一个例外是当您想要处理特定元素上的多个事件时:

// Template
<ul>
  {{#each post in controller}}
    {{#view App.PostView}}
      {{title}}
      {{#if view.showDetails}}
        <span>{{summary}}</span>
      {{/if}}
    {{/view}}
  {{/each}}
</ul>

// View
App.PostView = Ember.View.extend({
   tagName: li,
   classNames: ['post-item'],
   mouseEnter: function(event) {
     this.set('showDetails', true);
   },

   mouseLeave: function(event) {
     this.set('showDetails', false);
   }
});
Run Code Online (Sandbox Code Playgroud)

由于我们需要同时捕获mouseEntermouseLeave(分别显示和隐藏帖子的详细信息),最好在视图中执行它,避免模板中的过多逻辑.上面的替代方法是使用与我们想要处理的事件数量一样多的嵌套标记(在我们的例子中,2):

// Template
<ul>
  {{#each post in controller}}
    <li class="post-item" {{action showTheDetails post on="mouseEnter" target="controller"}}>
    <span class="dummy" {{action hideTheDetails post on="mouseLeave" target="controller"}}
      {{title}}
      {{#if post.showDetails}}
        <span>{{summary}}</span>
      {{/if}}
    </span<
    </li>
  {{/each}}
</ul>
Run Code Online (Sandbox Code Playgroud)

然后在控制器中:

// Controller
App.PostsController = Ember.ArrayController.extend({
   showTheDetails: function(event) {
     var post = event.context;
     post.set('showDetails', true);
   },

   hideTheDetails: function(event) {
     var post = event.context;
     post.set('showDetails', false);
   }
});
Run Code Online (Sandbox Code Playgroud)

但我认为你会同意这更加丑陋.看到这里.


如果您想使用Ember控件视图(Ember.TextField,Ember.TextArea等),您别无选择,只能在视图中捕获事件.因此,您可以在视图中扩展控件视图并定义事件处理程序:

// Template
<legend>Add a comment</legend>
{{view App.CommentInputField valueBinding="comment"}}

// View
App.CommentInputField = Ember.TextField.extend({ 
  focusOut: function(event) {
    this.get('controller').validateComment();
  },

  keyDown: function(event) {
    if (event.keyCode === 13) { // Enter key
      this.get('controller').createComment();
      return false;
    }
  }
});
Run Code Online (Sandbox Code Playgroud)