Я начинаю изучать Ember, и неясно, какой лучший, наиболее приемлемый или даже предназначенный для обработки событий. Допустимо ли проверять цель в аргументе события функции кликов, должен ли я создавать новое представление для каждого элемента, для которого требуется событие, отличное от {{action}}, или что-то совершенно другое?
Каков наилучший способ обработки событий в Ember.js?
Ответ 1
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);
}
});
Как нам нужно захватить как mouseEnter
, так и mouseLeave
(чтобы показать и скрыть детали сообщения соответственно), лучше сделать это в представлении, избегая слишком много логики в шаблонах. Альтернативным способом для этого было бы использовать столько вложенных тегов, сколько количество событий, которые мы хотим обработать (в нашем случае 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);
}
});
Но я думаю, вы согласитесь, что это уродливее. См. здесь.
В тех случаях, когда вы хотите использовать представления управления 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;
}
}
});