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

时间:2012-10-28 04:49:38

标签: ember.js

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

1 个答案:

答案 0 :(得分:8)

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

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

<form {{action validate target="controller"}}>
  // ...
</form>

上述例外情况是您希望处理特定元素上的多个事件:

// 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);
   }
});

由于我们需要同时捕获mouseEntermouseLeave(分别显示和隐藏帖子的详细信息),最好在View中执行此操作,避免模板中出现太多逻辑。上面的替代方法是使用与我们想要处理的事件数量一样多的嵌套标记(在我们的例子中,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>

然后在控制器中:

// 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);
   }
});

但我认为你会同意这更加丑陋。请参阅here


如果您想使用Ember控制视图(Ember.TextFieldEmber.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;
    }
  }
});