0

考虑以下场景:

<ListView>
     <ItemView>
         <div class="ticket-id">136</div>
         <div class="ticket-label">Hello everyone</div>
     </ItemView>
     <ItemView></ItemView>
     ... 500+ item views
</ListView>

每个项目视图都有相应的模型。ListView 通过遍历项目集合并创建新的 ItemView 来创建自己。

问题是 - 谁应该处理项目事件?

将它放在每个 ItemView 本身上是非常合乎逻辑和好的。这样我们就可以访问模型了。但是由于我们有大量的物品,这意味着我们将拥有相同数量的处理程序 - 可能是一个问题。另一种方法是在 ListView 级别处理它,但这样我们将查看 DOM 内部以检查票证 ID,例如,并且无权访问模型。

更新:另一个问题是正确删除这样的视图。如果我们在 ItemViews 上使用事件处理程序,那么我们需要将它们存储起来,以便以后删除每一个。如果它们上面什么都没有——它们应该被自动收集起来,因为它们只给了我们一个 html 字符串。

4

2 回答 2

3

如果您实际上没有看到性能问题,我不会过度优化。处理ItemView事件,因为这是有道理的。

如果您已经知道性能/内存问题,或者您遇到了一个问题,那么您的两个选项的组合可能是要走的路:ItemView 处理事件,但parent 中的事件ListView。这将要求您跟踪您的子视图

因此,如果您ItemView目前看起来像这样:

var ItemView = Backbone.View.extend({
    events: {
        "click .submit" : "onSubmitClicked"
    },

    onSubmitClicked: function() {
        //...
    }
});

你可以像这样重构它:

var ItemView = Backbone.View.extend({
    //give item a css class to scope the events
    cssClass: "item-view",

    initialize: function() {
        //set id attribute to the DOM element
        this.attributes["data-id"] = this.model.id;
    },
    onSubmitClicked: function() {
        //...
    }
});

并在列表视图中监听冒泡事件,并将它们代理到项目视图:

var Listview = Backbone.View.extend({
    events: {
        //scope child events by css class
        "click .item-view .submit" : "onItemSubmitClicked"
    },
    render function() {
        var childViews = this._childViews = {};

        this.collection.each(function(model) {
            //render the child views any way you want
            var itemView = new ItemView({model:model}).render();

            //keep a id->view map
            childViews[model.id] = itemView;
        });
    },
    //proxy events to the correct childview
    onItemSubmitClicked: function(event) {
        var itemView = this._childViews[$(event.target).attr('data-id')];
        itemView.onSubmitClicked(event);
    }
});

我以这种方式轻松地重构了现有视图,因为事件处理程序保持原样,并且只有侦听器代码被提升了一个档次。它确实带来了复杂性开销,但如果您需要优化性能,通常必须付出一些代价。

于 2013-01-18T11:11:41.543 回答
1

你提出了很好的观点。如果我是你(我已经列出了一个包含 100 个项目的列表,其中包含几个没有问题的事件处理程序),我会选择 ItemView 处理事件的逻辑项。

在您知道它有问题之前,我不会预先优化并使您的代码更复杂。

于 2013-01-18T10:47:09.467 回答