6

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

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

2 回答 2

10

你打电话时

this.collection.reset(filtered)

您正在丢弃旧数据并用新数据替换它。

相反,您要做的是拥有一个临时“集合”(数组或 Backbone.Collection)来保存过滤器的结果,这就是您用作将消息呈现到 DOM 的“数据源”。

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

  1. 只需在每种情况下(包括“所有”情况)呈现 filterMessages 函数的 [array] 输出 - 但不要将该结果反馈回原始集合。
  2. 创建第二个集合以接收 filterMessages 函数的结果,并再次呈现该集合,保持原始集合不变。
于 2012-04-12T16:50:23.823 回答
4

您可以使用Backbone.CollectionView,它允许您使用该visibleModelsFilter选项指定集合中的哪些模型当前可见。

设置代码...

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

消息列表查看代码...

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 回答