AngularJS - 通过多个模型进行过滤

5
这似乎很简单,但我找不到答案。
假设我有一个数据数组,其格式如下:
friends = [{name:'John', age:60, location:'Brighton', street:'Middle Street'},
{name:'Bob', age:5, location:'Brighton', street:'High Street'}];

现在,我想根据文本输入来过滤数据,如下所示:
<input ng-model="searchText">
<ul>
    <li ng-repeat="friend in friends | orderBy:'name' | filter:searchText">
    {{friend.name}} - {{friend.location}}</li>
</ul>

这个工作正常,但它根据friend对象的每个属性(名字、年龄、位置和街道)过滤输入文本。我想仅根据名字和位置进行过滤(忽略年龄和街道)。是否可以在没有自定义过滤器的情况下实现这一点?

4个回答

7

是的,可以通过将谓词传递给过滤器而不是字符串来实现:

<li ng-repeat="friend in friends | orderBy:'name' | filter:friendContainsSearchText">

$scope.friendContainsSearchText = function(friend) {
    return friend.name.indexOf($scope.searchText) >= 0 || friend.location.indexOf($scope.searchText) >= 0
}

谢谢,工作得很好。唯一值得一提的是,我需要将文本转换为小写并添加 if(!$scope.searchText) return 1; 才能使其正常工作。 - user2424495
请注意- 添加'if(!$scope.searchText) return 1;'将导致在未输入搜索文本的情况下返回所有结果(无过滤)。如果需要这样做,这种方法的优点就体现出来了。 - KayakDave

2
这是我们使用自定义过滤器的方法。
演示:http://plnkr.co/edit/q7tYjOvFjQHSR0QyGETj?p=preview
[array] | search:query:columns:operator

> query: this is the term you are looking for
> columns: an array of the names of the properties you want to look for (if empty, will use the angular filter with query)
> operator: a boolean to switch between OR (true) and AND (false, default)

HTML (超文本标记语言)
<ul>
  <li ng-repeat="item in list | search:query:['name','location']:operator">
    <pre>{{item | json}}</pre>
  </li>
</ul>

JavaScript
app.filter('search', function($filter) {
  return function(input, term, fields, operator) {
    if (!term) {
       return input;
    }

    fields || (fields = []);

    if (!fields.length) {
      return $filter('filter')(input, term);
    }

    operator || (operator = false); // true=OR, false=AND

    var filtered = [], valid;

    angular.forEach(input, function(value, key) {
      valid = !operator;
      for(var i in fields) {
        var index = value[fields[i]].toLowerCase().indexOf(term.toLowerCase());
        // OR : found any? valid
        if (operator && index >= 0) { 
          valid = true; break;
        } 
        // AND: not found once? invalid 
        else if (!operator && index < 0) { 
          valid = false; break;
        }
      }
      if (valid) {
        this.push(value);
      }
    }, filtered);

    return filtered;
  };
});

1

或者你可以使用:

<li ng-repeat="friend in friends | orderBy:'name' | filter:{ name :searchText}">


这可能是你想要的,除了searchText需要加上引号。filter:{ name: 'searchText' }。这将告诉Angular它是一个字符串而不是表达式。 - Adam
1
实际上,@Adam看看这个fiddle:http://jsfiddle.net/Dwesk/1/。它不适用于引号,但没有问题。 - KayakDave
你说得完全正确,我们在这种情况下需要一个表达式,我误解了最初的问题和答案。 - Adam

-1

您可以像这样放置多个过滤器...

<div>
    <input ng-model="Ctrl.firstName" />
    <input ng-model="Ctrl.age" />

    <li ng-repeat = "employee in Ctrl.employees | filter:{name:Ctrl.firstName} | filter:{age:Ctrl.age}">{{employee.firstName}}</li>
</div>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接