角度实现多搜索过滤器

时间:2016-04-20 21:48:38

标签: javascript angularjs search

我正在使用角度advanced search box,我想在我的角度页面中实现自定义过滤器,但我无法弄清楚如何在查询中处理一系列要求。假设我有几个符合以下格式的对象:

{
    "displayName":"John",
    "gender":"male",
    "type":"customer",
    "items": 3,
}

我希望能够用简单的英语搜索`任何名字都是John且属于Customer的人。“这是我目前为止的角度搜索代码:

app.filter('infoFilter', function() {
    return function(data, query) {
        var output = [];
        var index;

        //loop over the original array
        angular.forEach(data, function(row, index) {
            angular.forEach(query, function(input, value) {
                if(input) {
                    if(angular.isNumber(row[value]) && row[value] == input) {
                        output.push(row);
                    } else if(!angular.isNumber(row[value]) && row[value].toLowerCase().indexOf(input.toLowerCase()) > -1) {
                        output.push(row);
                    }
                }
            });
        });
        if(query) {
            return data;
        } else {
            return output;
        }
    }
});

查询以对象形式出现:

{
    "displayName":"John"
}

这适用于1个搜索参数。因此,如果我搜索John,我的表将更新以显示名为john的所有条目。但是,这对多搜索参数不起作用。所以如果查询看起来像这样:

{
    "displayName":"John",
    "gender":"Female"
}

我需要在output.push(row)之前立即应用所有参数。我到底该怎么做呢?

1 个答案:

答案 0 :(得分:3)

如果我理解正确,您希望过滤所有查询参数应用的行(AND)。我稍微修改了你的代码以实现这种行为。

app.filter('infoFilter', function() {
    return function(data, query) {
        var output = [];
        var index;

        //loop over the original array
        angular.forEach(data, function(row, index) {

            var pushRow = true;

            angular.forEach(query, function(input, value) {
                if(input) {
                    if(angular.isNumber(row[value]) && row[value] == input) {
                        return;
                    } else if(!angular.isNumber(row[value]) && row[value].toLowerCase().indexOf(input.toLowerCase()) > -1) {
                        return;
                    }
                }
                pushRow = false;
            });

            if (pushRow) {
                output.push(row);
            }
        });

        // This bit also seems to be the wrong way around in your code.
        if(!query) {
            return data;
        } else {
            return output;
        }
    }
});

修改

以下是使用javascripts built in array functions的同一过滤器的优化版本。

app.filter('infoFilter', function() {
    return function(data, query) {
        if(!query || !data) {
            return data;
        }

        return data.filter(function(row) {
            return Object.keys(query).every(function(key) {
                var rowValue = row[key];
                var queryValue = query[key];

                return (angular.isNumber(rowValue) && rowValue == input) ||
                        (angular.isString(rowValue) && rowValue.toLowerCase().indexOf(queryValue.toLowerCase()) > -1);
            });
        });
    };
});