我应该在哪里为ItemView定义事件和事件处理程序?

时间:2013-12-02 01:45:33

标签: marionette

我有一个简单的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  
});

2 个答案:

答案 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元素上,没有区别。