简体   繁体   English

Backbone.js过滤器

[英]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. 包含所有过滤器参数为int的数组。 like for example: [2,36,11] . 例如: [2,36,11] So the ints represent different filter options. 因此,整数表示不同的过滤器选项。 Then i match this array elements with another int that comes as a variable. 然后,我将此数组元素与另一个作​​为变量来的int进行匹配。 like 2 for example. 例如2 so if 2 is in this array the filter should go on and do its thing. 因此,如果2在此数组中,则过滤器应继续执行其操作。

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. 问题在于,只有在数组中的int不大于9的情况下,此函数才起作用。因此,如果filter选项之一为12则它将不起作用。 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. 但是可以说该数组的整数为1并且您选择了过滤器选项12上的过滤器,它将接受作为匹配并应渲染渲染对象,因为indexOf将其作为匹配对象。 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. 因此,因为标签是带有数字的字符串,所以您可以将st分割开,然后对每个元素与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/ 这是使用相同基本概念的快速提琴,只是删除了视图部分,因此打开控制台以查看每个过滤器的结果, http://jsfiddle.net/leighking2/gmtvt12p/

This happens because o.get('tags') is returning a String , as you mentioned in a comment. 发生这种情况是因为o.get('tags')返回String ,正如您在注释中提到的那样。

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] ). 您对_.indexOf(value, item)将对具有length属性并且可以使用数组表示法(例如value[0] )访问的任何值起作用。 You can check it by looking at underscore's source code for indexOf function . 您可以通过查看下划线的indexOf function源代码进行检查。

The String type of JavaScript fits this signature. JavaScript的String类型适合此签名。 You are actually executing your function over each character of the String : 您实际上是在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". 这就是为什么当您使用字符串“ 12”时它将匹配“ 1”或“ 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. 进行此转换后,可以按预期使用_.indexOf

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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