Filter backbone collection by attribute value
Asked Answered
K

2

43

I have a defined model and a collection:

var Box = Backbone.Model.extend({
    defaults: {
        x: 0,
        y: 0,
        w: 1,
        h: 1,
        color: "black"
    }

});

var Boxes = Backbone.Collection.extend({
    model: Box
});

When the collection is populated with the models, I need a new Boxes collection made out of Box models that have a specific color attribute contained in the complete collection, I do it this way:

var sorted = boxes.groupBy(function(box) {
    return box.get("color");
});


var red_boxes = _.first(_.values(_.pick(sorted, "red")));

var red_collection = new Boxes;

red_boxes.each(function(box){
    red_collection.add(box);
});

console.log(red_collection);

This works, but I find it a bit complicated and unefficient. Is there a way of doing this same thing in a more simple way?

Here is the code I described: http://jsfiddle.net/HB88W/1/

Kathrynkathryne answered 1/8, 2012 at 15:5 Comment(0)
R
83

I like returning a new instance of the collection. This makes these filtering methods chainable (boxes.byColor("red").bySize("L"), for example).

var Boxes = Backbone.Collection.extend({
    model: Box,

    byColor: function (color) {
        filtered = this.filter(function (box) {
            return box.get("color") === color;
        });
        return new Boxes(filtered);
    }
});

var red_boxes = boxes.byColor("red")
Roz answered 1/8, 2012 at 15:29 Comment(9)
Will this change cid in model?Judy
filterBy: function(attribute, value) { filtered = this.filter(function(box) { return box.get(attribute) === value; }); return new Boxes(filtered); }Rhesus
Why return a new Boxes(). I would write var Boxes = Backbone.Collection.extend({ model: Box, byColor: function(color) { return this.filter(function(box) { return box.get("color") === color; }); } });Hangchow
Is this using filter from Underscore.js?Washing
Marcoslhc: that won't return a Backbone collection but an array of modelsGoodill
Adding two related and interesting links: tech.pro/tutorial/1519/rendering-a-filtered-backbonecollection github.com/p3drosola/Backbone.VirtualCollectionCritta
@Judy No, it won't change the cid of the model. That would only happen if you initialized a new one or cloned it.Rhesus
you may want to declare the filtered variable in its scope (byColor function)Zr
@Washing I would assume so since Backbone is based on Underscore.Magnitogorsk
S
48

See http://backbonejs.org/#Collection-where

var red_boxes = boxes.where({color: "red"});

var red_collection = new Boxes(red_boxes);
Selfmastery answered 8/8, 2013 at 13:56 Comment(2)
where returns an array of the collection, rather than a collection object.Dilan
This is a great solution, unless you are forced into using an older version of Backbone that does not have "where" implemented yet.Washing

© 2022 - 2024 — McMap. All rights reserved.