从正在过滤的集合中删除模型

时间:2013-09-19 19:37:41

标签: javascript backbone.js underscore.js

我正在通过_.each()循环运行Backbone集合并删除项目,如果它们不符合某些条件。

出于某种原因,在过滤了大约一半的集合之后,循环总是停止。

我有两个理论:

  • 我注意到循环总是在集合中最后一个项目上结束。也许这些项以随机顺序传递给循环,但循环引用了集合的“实际”顺序。

  • 通过从正在过滤的同一个集合中删除项目,我搞乱了循环,它认为项目数量实际上比实际数量少。

这是一个有效的版本:http://jsfiddle.net/aZ9zJ/。有人能告诉我发生了什么事吗?

-

顺便说一句,我知道过滤_.filter()_.where()等函数,但更喜欢避免使用它们,因为它们返回数组而不是集合。

我愿意切换到过滤功能,但我仍然想了解为什么我正在尝试的每种/删除技术都不起作用。

App.View.Items = Backbone.View.extend({
    tagName: 'p',

    initialize: function() {
        Backbone.on('filter:now', this.filterItems, this);

        this.filtered = new Backbone.Collection;

        this.collection.each(function(item) {
            this.filtered.add(item);
        }, this);

        this.filters = new Backbone.Collection([
            {
                property: 'director',
                criteria: 'Orson Welles'
            }
        ]);

        Backbone.trigger('filter:now');
    },

    filterItems: function() {
        this.filters.each(function(filter) {
            this.filtered.each(function(item) {
                if ( item.get(filter.get('property')) === filter.get('criteria') ) {
                    this.filtered.remove(item);
                }
            }, this);
        }, this);

        console.log(this.filtered);
    }

});

未过滤的集合:

var itemCollection = new App.Collection.Items([
    {
        title: 'Citizen Kane',
        director: 'Orson Welles'
    },
    {
        title: 'Touch of Evil',
        director: 'Orson Welles'
    },
    {
        title: 'The Third Man',
        director: 'Orson Welles'
    },
    {
        title: 'Jaws',
        director: 'Steven Spielberg'
    },
    {
        title: 'Magnificent Ambersons',
        director: 'Orson Welles'
    }
]);

实例化视图:

var itemsView = new App.View.Items({ collection: itemCollection });

1 个答案:

答案 0 :(得分:1)

  

顺便说一句,我知道过滤函数如_.filter()和   _.where()但更喜欢避免它们,因为它们返回一个数组而不是一个集合。

但是你应该使用它们。

对正在过滤的集合进行混乱会改变其长度,因此结果可能无法预测。您应该filter您的收藏集,然后set您在其他收藏集上从此操作返回的数组。

this.filtered.set( this.collection.filter(function(item) {
            return item.get(filter.get('property')) === filter.get('criteria');
            }
))

http://jsfiddle.net/aZ9zJ/1/