angular ng-repeat如果匹配表达式则跳过项目


91

我正在寻找一种基本上告诉angular如果与表达式匹配的话跳过ng-repeat中的项目的方法continue

在控制器中:

$scope.players = [{
    name_key:'FirstPerson', first_name:'First', last_name:'Person'
}, {
    name_key:'SecondPerson', first_name:'Second', last_name:'Person'
}]

现在,在我的模板中,我想向所有人显示不匹配的人name_key='FirstPerson'。我认为它必须是过滤器,所以我设置了一个Plunkr来使用它,但是没有任何运气。Plunkr尝试


我试着理解:您是否要显示所有项目,但要指出谁匹配而谁不匹配?还是只是过滤器?
Maxim Shoustin

Answers:


144

正如@Maxim Shoustin所建议的那样,实现所需目标的最佳方法是使用自定义过滤器。
但是还有其他方法,其中一种方法ng-if是在放置指令的情况下在同一元素上使用ng-repeat指令(也是,这是plunker):

<ul>
    <li ng-repeat="player in players" ng-if="player.name_key!='FirstPerson'"></li>
</ul>

从美学的角度来看,这可能会带来一个次要的缺点,但是具有一个主要的优点,即您的过滤可以基于与players数组没有那么紧密耦合并且可以轻松访问应用范围内的其他数据的规则:

  <li 
      ng-repeat="player in players" 
      ng-if="app.loggedIn && player.name != user.name"
  ></li>

更新
如上所述,这是针对此类问题的解决方案之一,可能会或可能不会满足您的需求。
如注释中所指出的,它ng-if是一个指令,实际上意味着它在后台可能会比您预期的执行更多的操作。
例如,ng-if 从其父级创建一个新范围

ngIf中创建的范围使用原型继承从其父范围继承。

这通常不会影响正常行为,但是为了防止意外情况,在实施之前应牢记这一点。


这正是我在寻找的东西,知道没有自定义过滤器,必须有一些简短而甜美的方法。谢谢!
aron.duby

注意:ng-if的某些作用域行为可能很棘手。我尝试了这种方法,它在其他地方引起了问题。即,我有一个“观察者”指令,该指令在转发器完成时广播事件。将ng-if添加到此转发器后,它将不再触发该事件。自定义过滤器实际上可能是最干净的方法。
claywhipkey

@claywhipkey是正确的,最干净的方法是使用过滤器,但这并不适合所有情况。无论如何,请发表评论,您可以看到我在答案中添加了提示更新,目的是让任何人都知道使用指令过滤数据的含义。
gion_13 2015年

43

我知道这是一个古老的方法,但是如果有人要寻找另一种可能的解决方案,这是另一种解决方法-使用标准过滤器功能:

对象:模式对象可用于过滤数组包含的对象的特定属性。例如,{name:“ M”,phone:“ 1”}谓词将返回属性名称为“ M”且属性电话为“ 1”的项的数组。... 可以通过在字符串前面加上!来否定谓词。例如,{name:“!M”}谓词将返回属性名称不包含“ M”的项目数组。

因此,对于TS示例,应该执行以下操作:

<ul>
    <li ng-repeat="player in players | filter: { name_key: '!FirstPerson' }"></li>
</ul>

无需编写自定义过滤器,也无需使用ng-if它的新作用域。


简单点。没有作者定义的自定义过滤器或新作用域。非常适合跳过列表中的单个值。
mbokil,2015年

我认为您需要从“ player.name_key”中省略“ player”,因此在上面的示例中,它只是“ {name_key:'!FirstPerson'}”。
smithml

我从来没有办法让Angular的空键演奏效果不错。是否有某种技巧可以将内置过滤器用于等效于的过滤器player in players | filter: { name_key: '' }?该特定指令将仅与no / empty的玩家不匹配name_key。相反,name_key: '!'旨在选择任何非空玩家的方法name_key也将不起作用。
Eric L.

您可以检查答案。
Ilya Luzyanin 2015年

4
请注意,这仅适用于数组,不适用于对象属性,例如ng-repeat="(key, val) in player"
David Diez,2016年

19

实现时可以使用自定义过滤器ng-repeat。就像是:

 data-ng-repeat="player in players |  myfilter:search.name

myfilter.js

app.filter('myfilter', function() {


   return function( items, name) {
    var filtered = [];

    angular.forEach(items, function(item) {

      if(name == undefined || name == ''){
        filtered.push(item);
        }

      /* only if you want start With*/
      // else if(item.name_key.substring(0, name.length) !== name){
      //   filtered.push(item);
      // }

      /* if you want contains*/
      // else if(item.name_key.indexOf(name) < 0 ){
      //   filtered.push(item);
      // }

       /* if you want match full name*/
       else if(item.name_key !== name ){
        filtered.push(item);
      }
    });

    return filtered;
  };
});

演示版 Plunker


感谢您为此所做的工作。它绝对正确,但是我最终在代码中使用了@ gion_13的答案,所以我认为我最好将他标记为可接受的答案
aron.duby
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.