[英]How can I make Angular's 'filter' filter filter deeply?
Suppose I have some things in an array: 假设我在数组中有一些东西:
app.controller('ThingsController', function() {
this.things = [
{},
{
foo: 0,
},
{
foo: -1,
bar: null,
},
{
foo: 1,
bar: { a: true, b: true },
},
{
foo: 2,
bar: { a: true, b: false },
},
{
foo: 3,
bar: { a: false, b: true },
},
{
foo: 4,
bar: { a: false, b: false },
},
];
});
I want do display these things, and be able to filter the list based on some selection criteria. 我想显示这些内容,并能够根据某些选择条件过滤列表。 I may want to display only those things whose foo == 2
, or whose bar.a == true
, for instance. 例如,我可能只想显示foo == 2
或bar.a == true
那些东西。 So, I wire it up to this HTML: 因此,我将其连接到以下HTML:
<div ng-init="filterObj = {};">
foo: <input type="number" ng-model="filterObj.foo" />
a: <input type="checkbox" ng-model="filterObj.bar.a" />
b: <input type="checkbox" ng-model="filterObj.bar.b" />
<input type="reset" ng-click="filterObj = {};" />
<ul ng-controller="ThingsController as ctrl">
<li ng-repeat="thing in ctrl.things | filter: filterObj"><!-- content --></li>
</ul>
</div>
This way, filtering on foo
works just fine, but filtering on bar
does not work as intended, as you can see for yourself in this jsfiddle . 这样,对foo
过滤就可以了,但是对bar
过滤却无法按预期进行,正如您在jsfiddle中所看到的那样 。 Specifically, setting either of filterObj.bar.a
and filterObj.bar.b
to either true
or false
makes the filter match any truthy bar
. 具体来说,将filterObj.bar.a
和filterObj.bar.b
中的任何一个设置为true
或false
都会使过滤器与任何true bar
匹配。 Filtering through filter: filterObj : true
won't work either, since that would filter on exact deep equality (ie filterObj = { bar: { a: true } }
wouldn't match any of the above things). 通过filter: filterObj : true
也不起作用,因为这将根据精确的深度相等进行过滤(即filterObj = { bar: { a: true } }
与以上任何内容都不匹配)。
How can I make this filtering deep, so that filterObj = { bar: { a: true } }
would match the things above whose foo
is 1
or 2
but not the others? 我该如何进行深度过滤,以便filterObj = { bar: { a: true } }
会匹配foo
为1
或2
而不是其他foo
的东西? Will I need to write my own filter or comparator for this, or is there some trick I can use? 我需要为此编写自己的过滤器或比较器 ,还是可以使用一些技巧?
I got it to work using a custom comparator . 我让它使用自定义比较器工作 。 It got even simpler when I realized there's an underscore function for this exact comparison. 当我意识到有一个下划线功能进行这种精确比较时,它变得更加简单。
app.controller('ThingsController', function() {
this.things = [ /* ... */ ];
this.filterComparator = function(actual, expected) {
return _.matches(expected)(actual);
};
});
HTML: HTML:
<li ng-repeat="thing in ctrl.things | filter: filterObj : ctrl.filterComparator"><!-- content --></li>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.