Я использую окно углового расширенного поиска, и я хочу реализовать собственный фильтр на моей угловой странице, но мне трудно понять, как обрабатывать строку требований в запросе. Скажем, у меня есть несколько объектов, которые следуют следующему формату:
{
"displayName":"John",
"gender":"male",
"type":"customer",
"items": 3,
}
Я хотел бы иметь возможность искать на простом английском языке "Любой, кто зовет" Джон "и имеет тип" Клиент ". Вот мой угловой код поиска:
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)
. Как именно я буду заниматься этим?
Если я правильно вас понимаю, вы хотите отфильтровать строки, в которых применяются все параметры запроса (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, встроенные в функции массива.
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);
});
});
};
});
TypeError: Cannot read property 'filter' of undefined
. Есть идеи, о чем это?