Я новичок в AngularJS, и у меня проблемы с повторным использованием общего фильтра.
Скажем, у меня есть цвета, типы и список объектов, как показано ниже (New JSON). Я хочу создать общий фильтр, который будет принимать цвета и типы объектов и фильтровать объект списка без использования соответствия строки в качестве фильтра.
На данный момент я сделал специальные фильтры по строкам, как показано ниже.
У меня будет много информации в этих объектах, и я не хочу обновлять контроллер каждый раз, когда новое свойство включается в JSON.
Как связать номер с его конкретным строковым значением?
[
{
"id": 1,
"name": "Spike",
"type": "dog",
"color": "gray"
},
{
"id": 2,
"name": "Tom",
"type": "cat",
"color": "blue"
},
{
"id": 3,
"name": "Butch",
"type": "cat",
"color": "black"
}
]
// colors
[
{"gray": 1},
{"black": 2},
{"blue": 3},
]
// types
[
{"dog": 1},
{"cat": 2}
]
// data list
[
{
"id": 1,
"type": 1,
"name": "Spike",
"color": 1
},
{
"id": 2,
"type": 2,
"name": "Tom",
"color": 3
},
{
"id": 3,
"type": 2,
"name": "Butch",
"color": 2
}
]
<table class="table table-bordered table-condensed table-striped table-hover">
<thead>
<tr>
<th>
<a>
Filters:
</a>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in typeItems">
<td>
<label class="check">
<input type="checkbox" ng-model="typeFilterItems[item.type]">{{item.type}}
</label>
</td>
</tr>
<tr ng-repeat="item in colorItems">
<td>
<label class="check">
<input type="checkbox" ng-model="colorFilterItems[item.color]">{{item.color}
</label>
</td>
</tr>
</tbody>
</table>
<table class="table table-bordered table-condensed table-striped table-hover header-fixed">
<thead>
<tr>
<th>ID</th>
<th>Type</th>
<th>Color</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr class="list" ng-repeat="item in animals | filter:typeFilter | filter:colorFilter">
<td>{{item.id}</td>
<td>{{item.type}}</td>
<td>{{item.color}}</td>
<td>{{item.name}}</td>
</tr>
</tbody>
</table>
Контроллер
Animals.list().then(function (data) {
$scope.animals = data;
});
$scope.colorFilterItems = { 'black': true, 'gray': false, 'blue': false }; // doing this to have a predefined filter selection ... for now
$scope.colorItems = [{ name: 'black' }, { name: 'gray' }, { name: 'blue' }];
$scope.colorFilter = function (item) {
return $scope.colorFilterItems[item.color]
};
$scope.typeFilterItems = { 'dog': true, 'cat': false }; // doing this to have a predefined filter selection ... for now
$scope.typeItems = [{ name: 'black' }, { name: 'gray' }, { name: 'blue' }];
$scope.typeFilter = function (item) {
return $scope.typeFilterItems[item.type]
};
Поскольку никто не ответил, я в конце концов нашел решение.
Ответ на все это - использовать lodash непосредственно внутри службы и создать метод фильтрации внутри обещания, который ищет выбранное свойство внутри объектов фильтра и сравнивает их с данными, которые мы хотим отобразить.
filterAnimals = () => {
intersectedResults =
_.filter(animals,(animal: iAnimal) => {
var colors = _.find(colorLabels,(item: iFilter) => {
return (animal.color ? item.label === animal.color : item.label == null) && item.selected;
});
var types = _.find(typeLabels,(item: iFilter) => {
return (animal.type ? item.label === animal.type : item.label == null) && item.selected;
});
return colors && types;
});
return data;
};
После этого я получаю функцию filterAnimals() от контроллера и привязываю фильтры к моим данным. При выполнении ng-изменения на флажке эта функция выполняет и проверяет фильтры на данные, и она показывает нужные мне данные.