1

我对 Backbone 比较陌生,虽然我知道如何使用它的总体思路,但我的学习速度很快,而且我可能遗漏了一些关键元素。

所以我有一个集合,其中包含一个名为“类型”的属性,它可以是文章、书籍、视频、类。我有视图渲染和一切,但我需要能够在单击链接时过滤集合。

我的问题是- 当我点击另一种类型时,如何让它过滤集合并且仍然能够重新过滤原始集合?

这是我的代码的要点,为了便于阅读,我对其进行了简化:

var TagsView = Backbone.View.extend({
    initialize: function(query) {
        this.collection = new TagsCollection([], {query: self.apiQuery} );
        this.collection.on('sync', function() {
            self.render();
        });
        this.collection.on('reset', this.render, this);
    },
    render: function() {
        //renders the template just fine
    },
    filter: function() { 
        //filtered does work correctly the first time I click on it but not the second.
        var filtered = this.collection.where({'type':filter});
        this.collection.reset(filtered);
    }
});

更新:我设法让这个工作。我最终触发了一个过滤器事件。

var TagsCollection = Backbone.Collection.extend({
    initialize: function(model, options) {
        this.query = options.query;
        this.fetch();
    },
    url: function() {
        return '/api/assets?tag=' + this.query;
    },
    filterBy: function(filter) {
        filtered = this.filter(function(asset) {
            return asset.get('type') == filter;
        });
        this.trigger('filter');
        return new TagsCollection(filtered, {query: this.query});
    },
    model: AssetModel
});

然后在我看来,我添加了一些东西来渲染我的新系列。

var TagsView = Backbone.View.extend({
    initialize: function(query) {
        this.collection = new TagsCollection([], {query: self.apiQuery} );
        this.collection.on('sync', function() {
            self.render();
        });
        this.collection.on('filter sync', this.filterTemplate, this);
        this.collection.on('reset', this.render, this);
    },
    render: function() {
        //renders the template just fine
    },
    filterCollection: function(target) {
        var filter = $(target).text().toLowerCase().slice(0,-1);
        if (filter != 'al') {
            var filtered = this.collection.filterBy(filter);
        } else {
            this.render();
        }

    },
    filterTemplate: function() {
        filterResults = new TagsCollection(filtered, {query: self.apiQuery});
        console.log(filterResults);
        $('.asset').remove();
        filterResults.each(function(asset,index) {
            dust.render('dust/academy-card', asset.toJSON(),     function(error,output) {
                self.$el.append(output);
            });
        });
    },  
});
4

3 回答 3

2

它第二次不起作用的原因是因为您在调用时删除了与过滤器不匹配的模型reset。这是该功能的正常行为reset

不要使用视图的主集合进行渲染,而是尝试使用仅用于渲染的第二个集合,它表示原始基本集合的过滤数据。所以你的观点可能看起来像:

var TagsView = Backbone.View.extend({

    filter: null,

    events: {
        'click .filter-button': 'filter'
    },

    initialize: function (query) {
        this.baseCollection = new TagsCollection([], {query: self.apiQuery} );
        this.baseCollection.on('reset sync', this.filterCollection, this);
        this.collection = new Backbone.Collection;
        this.collection.on('reset', this.render, this);
    },

    render: function () {
        var self = this,
            data = this.collection.toJSON();

        // This renders all models in the one template
        dust.render('some-template', data, function (error, output) {
            self.$el.append(output);
        }); 
    },

    filter: function (e) { 
        // Grab filter from data attribute or however else you prefer
        this.filter = $(e.currentTarget).attr('data-filter');
        this.filterCollection();
    },

    filterCollection: function () { 
        var filtered;

        if (this.filter) {
            filtered = this.baseCollection.where({'type': this.filter});
        } else {
            filtered = this.baseCollection.models;
        }

        this.collection.reset(filtered);
    }

}); 

要删除任何过滤器,请将带有类的按钮设置filter-button为具有空data-filter属性。collection然后将使用所有baseCollection的模型重置

于 2013-08-31T05:56:40.570 回答
1

这是一个更好的答案。您可以使用 where 方法,而不是让它变得如此复杂。这是我对上述问题的替代解决方案。

filterby: function(type) {
      return type === 'all' ? this : new BaseCollection(this.where({type: type});
});
于 2015-06-18T21:40:03.243 回答
0

您可以尝试使用 Collection 的比较器功能。

http://backbonejs.org/#Collection-comparator

基本上它就像分类你的收藏。

于 2013-08-31T03:07:37.183 回答