Let's imagine I have various items stored in an array:
app.controller('ItemsController', function() {
this.items = [
{},
{
name: 'apple',
},
{
name: 'banana',
color: null,
},
{
name: 'orange',
color: { red: true, yellow: true },
},
{
name: 'grape',
color: { red: true, purple: false },
},
{
name: 'watermelon',
color: { red: false, green: true },
},
{
name: 'kiwi',
color: { red: false, green: false },
},
];
});
I would like to display these items and have the ability to filter the list based on certain criteria. For example, I might only want to display items with a specific name or those with a certain color attribute set to true. To achieve this, I link it to the following HTML structure:
<div ng-init="filterObj = {};">
Name: <input type="text" ng-model="filterObj.name" />
Red: <input type="checkbox" ng-model="filterObj.color.red" />
Yellow: <input type="checkbox" ng-model="filterObj.color.yellow" />
<input type="reset" ng-click="filterObj = {};" />
<ul ng-controller="ItemsController as ctrl">
<li ng-repeat="item in ctrl.items | filter: filterObj"><!-- content --></li>
</ul>
</div>
While filtering by name works correctly, filtering by color does not yield the expected results, which can be seen in this jsfiddle. Setting either of filterObj.color.red
orfilterObj.color.yellow
to true or false causes the filter to match any truthy values under color. Filtering using filter: filterObj : true
also does not solve the issue since it filters based on exact deep equality (i.e.,
filterObj = { color: { red: true } }
wouldn't match any of the listed items above).
How can I implement deep filtering so that
filterObj = { color: { red: true } }
matches items where the name is 'orange' or 'kiwi' but not others? Would I need to create a custom filter or comparator, or is there a workaround that I could utilize?