控制器中的角度嵌套过滤器

时间:2014-03-04 13:50:35

标签: javascript angularjs angularjs-scope angularjs-filter

我有按标题(字符串)或标签(字符串数组)搜索的项目

项目:

[
  {
    title: 'My title',
    tags: ['tag1', 'other']
  },
  {
    title: 'Misc',
    tags: ['tag1', 'notag']
  }
]

我想要一个输入来搜索标题OR标签

在我的模板中,这很有效:

<form>
    <input type="text" ng-model="query">
</form>

<li ng-repeat="item in items | filter:query:title | filter:query:tags">
    <p>{{item.title}}</p>
</li>

我的所有项目都会显示,如果我输入文字,则按标题或标签过滤。 例如: 我输入title,只返回第一个项目,如果我输入tag1,则返回两个项目。

现在,我需要在搜索过滤器的结果中设置另一个范围。

在我的控制器/指令中,我尝试过:

scope.filteredItems = $filter('filter')($filter('filter')(scope.items, {title: scope.query}), {tags: scope.query});

但我没有相同的结果,我错过了什么?

1 个答案:

答案 0 :(得分:1)

首先,您在HTML中错误地使用了过滤器。如果你看一下filter documentation,你会发现它需要一个表达式和一个比较器。因此,截至目前,在HTML中,您传递query作为表达式,titletags作为比较器,两者都未定义。

因为您传递的是字符串作为表达式,

  

将字符串计算为表达式,结果值为   用于子串匹配数组的内容。所有   包含此字符串的数组中字符串属性的字符串或对象   将返回字符串。

换句话说,搜索每个项目中的所有属性以查询查询。这就是为什么它似乎是按title和/或tags进行过滤。

然后,在您的控制器中,您将传递一个对象作为表达式。这使得它实际上只返回给定属性与给定值匹配的项目。但是,由于您要调用两次,因此您正在过滤titletagsquery匹配的项目。

有两种方法可以解决这个问题。

如果您不介意搜索query的所有字段,可以执行以下操作。在您的HTML中,替换为

<li ng-repeat="item in items | filter:query">

并在您的控制器中,替换为

$scope.filteredItems = $filter("filter")($scope.items, $scope.query);

但是,如果您只想搜索titletags,那就更复杂了。请参阅此文章,了解如何创建搜索多个字段的自定义过滤器:

How to filter multiple values (OR operation) in angularJS