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 自体にそれを配置するのは非常に論理的で便利です。このようにして、モデルにアクセスできます。しかし、大量のアイテムがあるため、ハンドラーの数が同じであることを意味します。これは問題になる可能性があります。もう 1 つの方法は、ListView レベルで処理することですが、この方法では、DOM 内を調べて、たとえばチケット ID をチェックし、モデルにアクセスできなくなります。

更新: 別の問題は、そのようなビューを正しく削除しています。ItemViews でイベント ハンドラーを使用する場合は、後でそれぞれを削除するためにそれらを保存する必要があります。それらに何もない場合-html文字列しか提供しないため、自動的にガベージ収集する必要があります。

4

2 に答える 2

3

実際にパフォーマンスの問題が発生していない場合は、過度に最適化することはありません。ItemViewそれが理にかなっているので、イベントを処理してください。

既知のパフォーマンス/メモリの問題がある場合、またはいずれ問題が発生する場合は、次の 2 つのオプションを組み合わせて実行することをItemView 勧めします。これには、子ビューを追跡する必要があります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 に答える