6

Backboneによって駆動されるアプリをセットアップしています。「Message」というモデル、「MessageList」というコレクション、「MessageView」や「MessageListView」というビューがあるという「単純なはず」の問題に直面しています。

MessageListViewコードは、MessageListをレンダリングします。MessageListViewの表示をフィルタリングする4つのトグルボタンがあります。フィルタボタンは、「すべて」、「アクティブ」、「フラグ付き」、および「無視」です。「すべて」は、ページ読み込み時の初期フィルターです。ユーザーが「フラグ付き」フィルターを押すと、フラグ==1のメッセージのみが表示されます。もう一度「すべて」を押すと、すべてのメッセージが再び表示されます。

私が遭遇している問題、および私のデザインの問題は、filterStringに基づいてコレクションをフィルター処理すると、元のコレクション全体への参照が失われることです。したがって、「すべて」をもう一度押すと、メッセージは失われます。

バックボーンでこれを行うための最良の方法について興味があります...

これがセットアップコードです...

    var messageListView = new MessageListView({collection: messageList});

これがMessageListViewコードです...

MessageListView = Backbone.View.extend({

    initialize : function() {

        this.collection.on("add", function(model) {
            var view = new MessageView({model: model});
            $("div.cameras").prepend(view.render().el);
        });

        this.collection.on("remove", function(model) {
            var ID = model.id;
            $("#message-" + ID).parent("div.message").remove();
        });

        this.collection.on("reset", function(models) {
            $("div.cameras").empty();
            models.each(function(message) {
                var view = new MessageView({model: message});
                $("div.cameras").prepend(view.render().el);
            });
        });

    },

    filterMessages : function(filterString) {
        var filtered = this.collection.filter(function(model){

            if (filterString == "all")
            {
                return true;
            }
            else if (filterString == "active")
            {
                return model.get("ignore") == "0";
            }
            else if (filterString == "ignore")
            {
                return model.get("ignore") == "1";
            }
            else if (filterString == "flag")
            {
                return model.get("flag") == true;
            }

        });
        this.collection.reset(filtered);
    },
4

2 に答える 2

10

電話するとき

this.collection.reset(filtered)

古いデータを破棄し、新しいデータに置き換えています。

代わりに実行したいのは、フィルターの結果を保持するための暫定的な「コレクション」(配列またはBackbone.Collection)を用意することです。これは、メッセージをDOMにレンダリングするための「データソース」として使用するものです。

これを行うにはいくつかの方法があります。

  1. filterMessages関数の[array]出力をすべての場合(「all」の場合を含む)にレンダリングするだけですが、その結果を元のコレクションにフィードバックしないでください。
  2. filterMessages関数の結果を受け取るために、2番目のコレクションを作成し、元のコレクションをそのままにして、そのコレクションを再度レンダリングします。
于 2012-04-12T16:50:23.823 に答える
4

Backbone.CollectionViewを使用できます。これにより、オプションを使用して、コレクション内のどのモデルを現在表示するかを指定できvisibleModelsFilterます。

セットアップコード...

var messageListView = new MessageListView( {
    collection: messageList,
    modelView : MessageView
} );

MessageListViewコード...

MessageListView = Backbone.CollectionView.extend( {

    filterMessages : function(filterString) {
        if (filterString == "all") {
            this.setOption( "visibleModelsFilter", null );
        }
        else if (filterString == "active") {
            this.setOption( "visibleModelsFilter", function( thisModel ) {
                return model.get("ignore") == "0";
            } );
        }
        else if (filterString == "ignore") {
            this.setOption( "visibleModelsFilter", function( thisModel ) {
                return model.get("ignore") == "1";
            } );
        }
        else if (filterString == "flag") {
            this.setOption( "visibleModelsFilter", function( thisModel ) {
                return model.get("flag") == true;
            } );
        }
    }

} );
于 2013-05-20T21:14:44.393 に答える