AngularJS过滤多个字符串

时间:2013-12-08 22:09:35

标签: angularjs

我正在学习AngularJS教程,并了解

的基础知识

但是,开箱即用的实现似乎仅限于将项目列表过滤为输入的确切字词或短语。

示例:如果查询是“桌布”,则结果列表可以包含此短语“装饰表布”的结果,但不包括“装饰布料表”,因为过滤器只是一个连续搜索字符串。

我知道有能力添加自定义过滤器,但乍一看似乎主要是变换。

有没有办法添加自定义过滤器,以便在过滤结果集中显示“装饰桌布”和“装饰桌布”?

6 个答案:

答案 0 :(得分:19)

对上述自定义过滤器的一些改进

不是在循环,计数和indexOf中使用循环,而是使用正则表达式来实现逻辑 AND 以及逻辑 OR < / strong>取决于过滤器的第三个参数(输入字符串数组,搜索项,AND或OR)

使用两种类型的过滤器和结果来查看分叉小提琴:

http://jsfiddle.net/jonjon/Cx3Pk/23/

angular.module('app', [])
    .filter("myFilter", function () {
    return function (input, searchText, AND_OR) {
        var returnArray = [],
            // Split on single or multi space
            splitext = searchText.toLowerCase().split(/\s+/),
            // Build Regexp with Logical AND using "look ahead assertions"
            regexp_and = "(?=.*" + splitext.join(")(?=.*") + ")",
            // Build Regexp with logicial OR
            regexp_or = searchText.toLowerCase().replace(/\s+/g, "|"),
            // Compile the regular expression
            re = new RegExp((AND_OR == "AND") ? regexp_and : regexp_or, "i");

        for (var x = 0; x < input.length; x++) {
            if (re.test(input[x])) returnArray.push(input[x]);
        }
        return returnArray;
    }
});

答案 1 :(得分:7)

请参阅下面的surfbuds回答,因为它更优秀

使用您自己的过滤器滚动:

.filter("myFilter", function(){
    return function(input, searchText){
        var returnArray = [];
        var searchTextSplit = searchText.toLowerCase().split(' ');
        for(var x = 0; x < input.length; x++){
            var count = 0;
            for(var y = 0; y < searchTextSplit.length; y++){
                if(input[x].toLowerCase().indexOf(searchTextSplit[y]) !== -1){
                    count++;
                }
            }
            if(count == searchTextSplit.length){
                 returnArray.push(input[x]);   
            }
        }
        return returnArray;
    }
});

jsfiddle http://jsfiddle.net/Cq3PF/

此过滤器可确保找到所有搜索字词。

答案 2 :(得分:3)

或者,您可以在自定义过滤器中使用默认的角度过滤器,如下所示:

angular.module('app').filter("multiWordFilter", function($filter){
    return function(inputArray, searchText){
        var wordArray = searchText ? searchText.toLowerCase().split(/\s+/) : [];
        var wordCount = wordArray.length;
        for(var i=0;i<wordCount;i++){
            inputArray = $filter('filter')(inputArray, wordArray[i]);
        }
        return inputArray;
    }
});

这可以通过user2005009的AND_OR比较器进一步修饰。

答案 3 :(得分:0)

这是我的版本。它使用了JonoWilko使用内置filterFilter结合surfbud的AND / OR标志的方法(默认为"AND")。

<强>的JavaScript

angular.module('filters').filter('searchFilter', function($filter) {

    return function(inputArray, searchText, booleanOp) {
        booleanOp = booleanOp || 'AND';

        var searchTerms = (searchText || '').toLowerCase().split(/\s+/);

        if (booleanOp === 'AND') {
            var result = inputArray;
            searchTerms.forEach(function(searchTerm) {
                result = $filter('filter')(result, searchTerm);
            });

        } else {
            var result = [];
            searchTerms.forEach(function(searchTerm) {
                result = result.concat($filter('filter')(inputArray, searchTerm));
            });
        }

        return result;
    };
});

<强>的CoffeeScript

angular.module('filters').filter 'searchFilter', ($filter)->

    (inputArray, searchText='', booleanOp = 'AND')->
        searchTerms = searchText.toLowerCase().split(/\s+/)

        if booleanOp is 'AND'
            result = inputArray
            searchTerms.forEach (word)->
                result = $filter('filter')(result, word)

        else
            result = []
            searchTerms.forEach (word)->
                result = result.concat $filter('filter')(inputArray, word)

        result

'AND'用法(默认)

<div ng-repeat="product in products | searchFilter: searchInputText"></div>

'或'使用

<div ng-repeat="product in products | searchFilter: searchInputText : 'OR'"></div>

答案 4 :(得分:0)

您可以按如下方式对对象进行多字搜索:

.filter("myFilter", function(){
    return function(input, searchText){
         var returnArray = [];
         var searchTextSplit = searchText.toLowerCase().split(' ');
        for(var x = 0; x < input.length; x++){
             var count = 0;
            for(var y = 0; y < searchTextSplit.length; y++){
                angular.forEach(input[x], function(item){
                    if(item.toLowerCase().indexOf(searchTextSplit[y]) !== -1){
                        count++;
                    }
                });

            }
            if(count == searchTextSplit.length){
                 returnArray.push(input[x]);   
            }
        }
        return returnArray;
    }
});    

Working demo in js fiddle

答案 5 :(得分:0)

不是一个班轮,但仍然很短而有趣

app.filter("filterall",function($filter) {
    return function(arr,t){
        (t?t.split(/\s+/):[]).forEach(function(v){ arr = $filter('filter')(arr,v); });
        return arr;
    };
});