【问题标题】:angularjs - filter by multiple modelsangularjs - 按多个模型过滤
【发布时间】:2013-10-20 01:07:57
【问题描述】:

这看起来一定很简单,我就是找不到答案。

假设我有一个数据数组,如下所示:

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>

这很好用,但它会根据朋友对象的每个属性(姓名、年龄、位置和街道)过滤输入文本。我希望能够仅根据名称和位置进行过滤(忽略年龄和街道)。如果没有自定义过滤器,这可能吗?

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    这是我们使用自定义过滤器的方法。

    演示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>
    

    js

    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;
      };
    });
    

    【讨论】:

      【解决方案2】:

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

      <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>
      

      【讨论】:

        【解决方案3】:

        您也可以使用:

        &lt;li ng-repeat="friend in friends | orderBy:'name' | filter:{ name :searchText}"&gt;

        【讨论】:

        • 这可能是你想要的,除了 searchText 需要引号。过滤器:{名称:'searchText'}。这将告诉 Angular 它是一个字符串而不是一个表达式。
        • 实际上@Adam 看看这个小提琴:jsfiddle.net/Dwesk/1 它不适用于引号,没有引号。
        • 你说的很对,在这种情况下我们想要一个表达式,我误解了最初的问题和答案。
        【解决方案4】:

        是的,只需将谓词而不是字符串传递给过滤器即可:

        <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;让它工作。
        • 请注意 - 添加 'if(!$scope.searchText) return 1;'如果没有输入搜索文本,将导致它返回所有结果(不过滤)。如果你需要的话,这是我列出的方法的一个优点。
        猜你喜欢
        • 2014-06-20
        • 2017-01-23
        • 1970-01-01
        • 1970-01-01
        • 2012-10-24
        • 1970-01-01
        • 2019-07-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多