简体   繁体   中英

Backbone.js filter

I'm trying to get a filter function to work properly. The function takes an array as param. The array containing all the filter params as ints. like for example: [2,36,11] . So the ints represent different filter options. Then i match this array elements with another int that comes as a variable. like 2 for example. so if 2 is in this array the filter should go on and do its thing.

The problem is that this function only works as long as the ints in the array not are higher than 9. So if one of the filter option is 12 it won't work. But lets say the array has an int wich is 1 and you choose the filer on filter option 12 it will accept that as a match and render wathever should be rendered, since indexOf takes it as a match. How can i solve this quite weird behaviour?

filter: function(f) { 
    var filter = this.collection.filter(function(o){ 
        var accept = false;                                    
        $(f).each(function(i,val){
            if(_.indexOf(o.get('tags'), val) >-1){
                accept = true;                      
            }
        })
        return accept; 
    });

    var filtered = new PeopleCollection(filter);
    new PeopleView({
        el: this.$('.peoplelist'),
        collection: filtered
    });
}

So as tags is a string with the numbers you can split the sting on , and then do a straight comparison on each element against the val.

 filter: function(f) {
     var filter = this.collection.filter(function(o) {
         var accept = false;
         $(f).each(function(i, val) {
             //only run if accept is false
             if (!accept) {
                 //if tags is a string of numbers spereated by commas
                 //turn that string into array and test each one against the val
                 _.forEach(o.get('tags').split(","), function(tag) {
                     if (accept) {
                         return;
                     }

                     //use parseInt to ensure both are numbers
                     if (parseInt(tag) === parseInt(val)) {
                         accept = true;
                     }
                 });
             }

         })
         return accept;
     });

     var filtered = new PeopleCollection(filter);
     new PeopleView({
         el: this.$('.peoplelist'),
         collection: filtered
     });
 }

here is a quick fiddle using the same base concept, just removed the view part so open your console to see the results of each filter, http://jsfiddle.net/leighking2/gmtvt12p/

This happens because o.get('tags') is returning a String , as you mentioned in a comment.

Your use of _.indexOf(value, item) will work on any value that has a length property and can be accessed with array notation (eg value[0] ). You can check it by looking at underscore's source code for indexOf function .

The String type of JavaScript fits this signature. You are actually executing your function over each character of the String :

'1,2,3'.length // 5
'1,2,3'[0] // '1'
'1,2,3'[1] // ','

This is why when you have the string "12" it will match either "1" or "2".

To convert your string to an array of numbers, you can do something like this:

'1,2,3'.split(',').map(function(x) { return parseInt(x, 10); }); // [1, 2, 3]

After this conversion, you can use _.indexOf as you expect.

So, try this:

filter: function(f) { 
    var filter = this.collection.filter(function(o){ 
        var accept = false;                                    
        $(f).each(function(i,val){
            var tags = o.get('tags').split(',').map(function(x) { // <-
                return parseInt(x, 10);                           // <-
            });                                                   // <-   
            if(_.indexOf(tags, parseInt(val, 10)) >-1){           // <-
                accept = true;                      
            }
        })
        return accept; 
    });

    var filtered = new PeopleCollection(filter);
    new PeopleView({
        el: this.$('.peoplelist'),
        collection: filtered
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM