我有一个简单的CollectionView和ItemView如下:
var CommentView = Mariontete.ItemView.extend({
tagName: 'li'
});
var CommentsView = Marionette.CollectionView.extend({
itemView: CommentView,
events : {
'click li' : 'onCommentClick'
},
onCommentClick: function(){}
});
我的问题是我应该在哪里为CommentView定义事件和事件处理程序,我把它放在Commentview中?或评论查看?如上所述?
如果我将它放在CommentView中,如下所示,我是否会因为在每个“li”标签上附加事件而失去性能? :
var CommentView = Mariontete.ItemView.extend({
tagName: 'li',
events : {
'click' : 'onCommentClick'
},
onCommentClick: function(){}
});
var CommentsView = Marionette.CollectionView.extend({
itemView: CommentView
});
答案 0 :(得分:1)
好问题 - 每种方法都有好处和缺点。使用事件委派(如在第一个示例中)允许您对所有注释单击事件使用单个处理程序。但是,由于您不再在原始视图的上下文中操作,因此如果您需要该视图中的特定知识,则代码可能会变得有点棘手。直接将事件处理程序附加到每个视图可以解决这个问题,但肯定会导致性能下降 - 特别是如果您的集合中有很多项目。
有几种方法可以解决这个问题。首先要考虑的是您希望在项目视图中有多少项目。如果我的收藏品是> 20件物品,我通常对视图级别的事件处理程序感到不舒服,但在此之下你应该没问题。
接下来要考虑的是在处理事件时您需要访问哪些信息。如果您不需要任何特定于项目的知识,那么实际上没有理由将处理程序附加到每个视图。
最后,如果你有很多项目并且你需要特定于视图的信息,那么事情会变得棘手。通常我会看到人们将模型数据填充到该视图元素中的data-xxx
属性中,但这对我来说就像添加显式事件处理程序一样笨拙。我使用的方法是利用jQuery的index()
方法来确定被点击的项目视图的索引,然后使用它来定位视图。然后我可以直接使用视图。
这是一个应该与您的代码一起使用的示例,假设您的LI内部没有任何内容:
handleClick: function(e) {
var ix = $(e.target).index(),
view = this.children.findByIndex(ix),
model = view.model.toJSON();
... do something amazing here
}
如果你的项目视图更复杂,那么事件的目标可能最终成为子元素。在这种情况下,您需要执行$(e.target).parent('li').index()
之类的操作,而不是找到正确的根$el
,但您明白了。
答案 1 :(得分:0)
逻辑应该很简单:照顾自己的事业。
您尚未说明点击li
的目的。也许您想扩展li以查看详细信息,或者想要启动管理对话框。无论出于何种原因我都可以猜到,这个动作只能看到一个特定的itemView,但与collectionView无关。
所以,只需在itemView中观看此事件即可。根本不要打扰collectionView。
对于表演,我不认为在这种情况下应该考虑这个问题。即使你看了collectionView,事件监听器最终也会附加到那些特定的DOM元素上,没有区别。