Решение
Ответ Серджио ниже работал отлично, в частности, функция objectsMatch, которую он предоставил. Мне также нужно поддерживать элементы выбора для множественного выбора для фильтрации, поэтому я немного изменил его функцию, вот он, если кто-то ищет аналогичную функциональность:
function objectsMatch(roll, filterObject) {
var match = true;
for (var prop in filterObject) {
if(!roll.hasOwnProperty(prop) ||
!filterObject.hasOwnProperty(prop)) continue;
if(Array.isArray(filterObject[prop])){
var matchesNoValues = function(){
for(var i = 0; i < filterObject[prop].length; i++){
console.log(filterObject[prop][i])
if(roll[prop] == filterObject[prop][i]){
return false;
}
}
return true;
}
if (matchesNoValues() &&
filterObject[prop] != ''
) {
match = false;
}
}else{
if (roll[prop] != filterObject[prop] &&
filterObject[prop] != ''
) {
match = false;
}
}
}
return match;
}
ИЗМЕНИТЬ 1
Я смог воспроизвести функциональность, которую я ищу в MVP здесь. И теперь я пытаюсь понять, как применить это к моему фильтру. Надеюсь, это может лучше продемонстрировать то, что я пытаюсь достичь.
Оригинальное сообщение
Я пытаюсь добавить настраиваемый фильтр для фильтрации строк в таблице в Angular. Мне нужно проверить, имеет ли каждый объект в моем повторе все значения, представленные в моем массиве фильтров. Эти значения устанавливаются элементами выбора в моей таблице.
Например, мой набор данных выглядит так:
$scope.sushi = [
{ name: 'Cali Roll', fish: 'Crab', tastiness: 2 },
{ name: 'Philly', fish: 'Tuna', tastiness: 4 },
{ name: 'Tiger', fish: 'Eel', tastiness: 7 },
{ name: 'Tiger', fish: 'Tuna', tastiness: 3 },
{ name: 'Rainbow', fish: 'Variety', tastiness: 62 }
];
И скажем, что мой фильтр содержит:
var filters = ['Philly', 'Tuna', 4];
он будет показывать только
$scope.sushi[1]
в повторении.
Затем скажем, что значения массивов фильтров обновляются:
var filters = ['Philly', 'Tuna', 1000];
Теперь никакие строки не будут отображаться, потому что в моем наборе данных нет объекта, который содержит все значения в массиве фильтров.
ЗДЕСЬ - ссылка на то, что я пробовал до сих пор, с обоими методами, отмеченными соответственно МЕТОДОМ 1 и МЕТОДОМ 2.
Я думаю, что я почти там с МЕТОДОМ 1, но если я выберу несколько значений, которые находятся в объекте, строки не будут отображаться, он отображает только строку, когда я выбираю только один фильтр. Что касается МЕТОДА 2, то только проверка того, что по крайней мере одно из значений в массиве фильтров находится в объекте, а не во всех.
Вот полный код в моем фильтре:
.filter('byColumn', function(){
return function(rolls, filterVal){
var filtered = [];
var test = true;
for(var x in rolls){
var currentRoll = rolls[x];
for(y in currentRoll){
// METHOD 1
var allMatches = true;
for(var i = 0; i < filterVal.length; i++){
if(filterVal[i]){
if(currentRoll[y] == filterVal[i]){
continue;
}else{
allMatches = false;
break;
}
}
}
if(allMatches){
if (filtered.indexOf(currentRoll) == -1) {
filtered.push(currentRoll);
}
}
if(!allMatches){
rolls = [];
}
// METHOD 2
// angular.forEach(filterVal, function(filter){
// if(currentRoll[y] == filter){
// if (filtered.indexOf(currentRoll) == -1) {
// filtered.push(currentRoll);
// }
// }
// });
}
}
return filtered.length ? filtered : rolls;
}
});
Код основан на учебнике Scotch.io, найденном здесь, который я изменил, чтобы соответствовать моим потребностям.
Спасибо заранее за любые предложения.
Вы можете перейти к byColumn фильтровать объект columnFilter вместо массива фильтров
будет выглядеть так:
<tr ng-repeat="roll in sushi | orderBy:sortType:sortReverse | filter:searchFish | byColumn:columnFilter track by $index">
<td>{{ roll.name }}</td>
<td>{{ roll.fish }}</td>
<td>{{ roll.tastiness }}</td>
</tr>
byColumn фильтр может выглядеть следующим образом:
.filter('byColumn', function(){
return function(rolls, filterVal){
var filtered = [];
for(var x in rolls){
var currentRoll = rolls[x];
if(objectsMatch(currentRoll, filterObject)) {
filtered.push(currentRoll);
}
}
return filtered;
};
})
И это функция objectsMatch
function objectsMatch(roll, filterObject) {
var match = true;
for (var prop in filterObject) {
if(!roll.hasOwnProperty(prop) ||
!filterObject.hasOwnProperty(prop)) continue;
if (roll[prop] != filterObject[prop] && filterObject[prop] != '')
{
match = false;
}
}
return match;
}
Fiddle Здесь
Надеюсь, что это работает для вас!