Backbone Collection - 过滤和渲染集合会丢失对原始未过滤集合的引用

时间:2012-04-12 16:21:59

标签: javascript backbone.js

我正在设置一个由Backbone驱动的应用程序。我面临一个“应该是简单的”问题,我有一个名为“Message”的模型,一个名为“MessageList”的Collection,以及名为“MessageView”和“MessageListView”的Views。

MessageListView代码呈现MessageList。我有4个切换按钮,用于过滤MessageListView显示的内容。过滤器按钮为“全部”,“活动”,“标记”和“忽略”。 “全部”是页面加载的初始过滤器。当用户按下“已标记”过滤器时,只会出现带有标志== 1的消息。再次按下“全部”时,所有信息应再次出现。

我遇到的问题,以及我的设计中的问题是,当我根据filterString过滤Collection时,对原始整个Collection的引用会丢失。因此,当再次按下“全部”时,消息已丢失。

我很想知道在Backbone中做到这一点的最好方法......

这是设置代码......

    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);
    },

2 个答案:

答案 0 :(得分:10)

致电时

this.collection.reset(filtered)

您丢弃旧数据并将其替换为新数据。

您要做的是使用临时“集合”(数组或Backbone.Collection)来保存过滤器的结果,这就是您用作将数据呈现给DOM的“数据源”

有几种方法可以做到这一点。

  1. 只需渲染filterMessages函数的[array]输出(包括'all'情况) - 但不要将该结果反馈回原始集合。
  2. 创建第二个集合以接收filterMessages函数的结果,并再次渲染该函数,保留原始集合。

答案 1 :(得分: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;
            } );
        }
    }

} );