【问题标题】:Multiple filter values in one input field (seperated by space) with AngularJS使用 AngularJS 在一个输入字段(以空格分隔)中的多个过滤器值
【发布时间】:2015-08-04 16:05:30
【问题描述】:

我有一组这样显示的人:

<div ng-repeat="person in persons | filterBy:filter">
  <div>{{person.name}}</div>
  <div>{{person.age}}</div>
  <div>{{person.city}}</div>
  <div>{{person.country}}</div>
</div>

我的过滤器绑定到一个文本输入字段。

现在我想在我的输入字段中输入多个搜索条件(以空格分隔)。类似于 “peter 28 berlin”。现在 Angular 应该只显示在 “28” 生活在 “berlin” 的名为 “peter” 的人。

有没有简单的方法来实现这一点?

【问题讨论】:

    标签: angularjs angularjs-ng-repeat ng-repeat


    【解决方案1】:

    如果您想要此功能,则必须编写自定义过滤器。不过其实也没那么复杂。

    var app = angular.module('filter', [])
    app.controller('MainController', function($scope) {
        $scope.persons = [
            {name: 'Peter', age: 28, city: 'Berlin'},
            {name: 'Malik', age: 23, city: 'London'},
            {name: 'Sofia', age: 31, city: 'Paris'},
        ];
    });
    
    
    // filterBy implementation
    app.filter('filterBy', function() {
        return function(array, query) {
        
            var parts = query && query.trim().split(/\s+/),
                keys = Object.keys(array[0]);
        
            if (!parts || !parts.length) return array;
        
            return array.filter(function(obj) {
                return parts.every(function(part) {
                    return keys.some(function(key) {
                        return String(obj[key]).toLowerCase().indexOf(part.toLowerCase()) > -1;
                    });
                });
            });
        };
    });
    .section {padding: 10px; margin-top: 10px; background: #EEE;}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.js"></script>
    <div ng-app="filter" ng-controller="MainController">
        <input type="text" ng-model="filter">
        <div class="section" ng-repeat="person in persons | filterBy:filter">
            <div>{{person.name}}</div>
            <div>{{person.age}}</div>
            <div>{{person.city}}</div>
        </div>
    </div>

    【讨论】:

    • 非常感谢...正是我所需要的
    【解决方案2】:

    不可能(或至少不是很容易)按照您的要求进行操作,因为需要一些逻辑来确定对象上的每个属性(姓名、年龄、城市、国家...)单词应该匹配。但是,您可以输入您的输入属性:值对,例如:'name:peter age:28 city:berlin' 并使用以下代码(注意,它是伪代码,因此可能包含小错误):

    <input ng-model="inputFilter"></input>
    
    <div ng-repeat="person in persons | filter:myPersonFilter">
        <div>{{person.name}}</div>
        <div>{{person.age}}</div>
        <div>{{person.city}}</div>
        <div>{{person.country}}</div>
    </div>
    
    $scope.myPersonFilter(person) {
        if ($scope.inputFilter) {
            var filters = $scope.inputFilter.split(' ');
            var isMatch = true;
    
            filters.forEach(function(filter) {
                var pair = filter.split(':');
    
                if (pair.length === 2) {
                    isMatch = (isMatch && (person[pair[0]] == pair[1]));
                }
            });
    
            return isMatch;
        }
    };
    

    请注意,有很多事情要记住:

    • 在您键入时,您可能会在列表中看到很多跳跃/闪烁,除非您在输入中添加某种类型的去抖动以限制过滤

    • 上面的实现只对属性进行相等比较,所以如果你有一个名为peter的人,那么'name:pet'的过滤器将不起作用。相反,您可能想要更改比较器以检查子字符串。

    • 此实现不适用于同一属性上的多个过滤器。例如,如果您想返回所有名为 Peter 或名为 Bob 的人,它就不会很好地工作。

    • 通常,当您想通过多个属性开始过滤时,最好构建一个过滤界面而不是使用单个输入字段。

    • 如果这将成为您应用的一项重要功能,您可能需要考虑将过滤移至应用的服务器端(如果存在)。

    【讨论】:

      猜你喜欢
      • 2014-01-25
      • 1970-01-01
      • 1970-01-01
      • 2021-06-12
      • 2020-11-24
      • 1970-01-01
      • 2020-03-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多