【问题标题】:Angular.js ng-repeat filter by property having one of multiple values (OR of values)Angular.js ng-repeat 按具有多个值之一(或值)的属性过滤
【发布时间】:2023-04-08 20:22:02
【问题描述】:

是否可以过滤对象数组,使得属性的值可以是几个值中的一个(或条件)无需编写自定义过滤器

这和这个问题类似——Angular.js ng-repeat :filter by single field

但不是

<div ng-repeat="product in products | filter: { color: 'red' }">

有没有可能做这样的事情

<div ng-repeat="product in products | filter: { color: 'red'||'blue' }">

如下示例数据-

$scope.products = [
   { id: 1, name: 'test', color: 'red' },
   { id: 2, name: 'bob', color: 'blue' }
   /*... etc... */
];

我试过了

<div ng-repeat="product in products | filter: { color: ('red'||'blue') }">

【问题讨论】:

标签: javascript angularjs angularjs-ng-repeat angularjs-filter


【解决方案1】:

最好的方法是使用函数:

<div ng-repeat="product in products | filter: myFilter">

$scope.myFilter = function (item) { 
    return item === 'red' || item === 'blue'; 
};

或者,您可以使用ngHide or ngShow 根据特定条件动态显示和隐藏元素。

【讨论】:

  • 除了一个函数或一个自定义过滤器,没有办法内联吗? ngHide 会将display 设置为none,但div 将被生成并插入到DOM 中。无论如何,我认为函数是最干净的方法,只是好奇是否有语法来内联指定 OR 条件。
  • @Sherlock 更准确地说,您应该添加颜色属性:$scope.myFilter = function (item) { return item.color === 'red' || item.color === 'blue'; };
【解决方案2】:

我找到了一个更通用的solution,它是我能想到的最原始的解决方案。基本上,您可以将自己的比较器传递给默认的filterFilter 函数。这里也是plunker

【讨论】:

    【解决方案3】:

    在 HTML 中:

    &lt;div ng-repeat="product in products | filter: colorFilter"&gt;

    在 Angular 中:

    $scope.colorFilter = function (item) { 
      if (item.color === 'red' || item.color === 'blue') {
      return item;
     }
    };
    

    【讨论】:

    • 谢谢,但如果您仔细阅读问题,我想要一个解决方案无需编写自定义过滤器
    【解决方案4】:

    我认为ng-if 应该可以工作:

    <div ng-repeat="product in products" ng-if="product.color === 'red' 
    || product.color === 'blue'">
    

    【讨论】:

    • 这可行,但$index 将引用原始数组索引
    【解决方案5】:

    这是一种在传递额外参数时执行此操作的方法:

    https://stackoverflow.com/a/17813797/4533488(感谢 Denis Pshenov)

    <div ng-repeat="group in groups">
        <li ng-repeat="friend in friends | filter:weDontLike(group.enemy.name)">
            <span>{{friend.name}}</span>
        <li>
    </div>
    

    与后端:

    $scope.weDontLike = function(name) {
        return function(friend) {
            return friend.name != name;
        }
    }
    

    .


    还有另一种仅使用模板内过滤器的方法:

    https://stackoverflow.com/a/12528093/4533488(感谢 mikel)

    <div ng:app>
      <div ng-controller="HelloCntl">
        <ul>
           <li ng-repeat="friend in friends | filter:{name:'!Adam'}">
                <span>{{friend.name}}</span>
                <span>{{friend.phone}}</span>
            </li>
        </ul>
    </div>
    

    【讨论】:

      【解决方案6】:

      对我来说,它的工作原理如下:

      <div ng-repeat="product in products | filter: { color: 'red'||'blue' }">
      
      <div ng-repeat="product in products | filter: { color: 'red'} | filter: { color:'blue' }">
      

      【讨论】:

      • 这不是更像一个“和”条件吗?
      【解决方案7】:

      在找不到一个好的通用解决方案后,我自己制作了一些东西。我还没有针对非常大的列表对其进行测试。

      它负责嵌套键、数组或任何东西。

      这里是githubdemo

      app.filter('xf', function() {
          function keyfind(f, obj) {
              if (obj === undefined)
                  return -1;
              else {
                  var sf = f.split(".");
                  if (sf.length <= 1) {
                      return obj[sf[0]];
                  } else {
                      var newobj = obj[sf[0]];
                      sf.splice(0, 1);
                      return keyfind(sf.join("."), newobj)
                  }
              }
      
          }
          return function(input, clause, fields) {
              var out = [];
              if (clause && clause.query && clause.query.length > 0) {
                  clause.query = String(clause.query).toLowerCase();
                  angular.forEach(input, function(cp) {
                      for (var i = 0; i < fields.length; i++) {
                          var haystack = String(keyfind(fields[i], cp)).toLowerCase();
                          if (haystack.indexOf(clause.query) > -1) {
                              out.push(cp);
                              break;
                          }
                      }
                  })
              } else {
                  angular.forEach(input, function(cp) {
                      out.push(cp);
                  })
              }
              return out;
          }
      
      })
      

      HTML

      <input ng-model="search.query" type="text" placeholder="search by any property">
      <div ng-repeat="product in products |  xf:search:['color','name']">
      ...
      </div>
      

      【讨论】:

        猜你喜欢
        • 2014-05-30
        • 2014-07-24
        • 2015-07-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多