Winkel ng-repeat Überspringe ein Element, wenn es mit dem Ausdruck übereinstimmt

91

Ich suche nach einer Möglichkeit, Angular grundsätzlich anzuweisen, ein Element in einer ng-Wiederholung zu überspringen, wenn es im Grunde einem Ausdruck entspricht continue.

In der Steuerung:

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

Jetzt möchte ich in meiner Vorlage alle anzeigen, die nicht übereinstimmen name_key='FirstPerson'. Ich dachte, es müssen Filter sein, also habe ich einen Plunkr eingerichtet, um damit herumzuspielen, aber ich hatte kein Glück. Plunkr Versuch

aron.duby
quelle
Ich versuche zu verstehen: Möchten Sie alle Elemente anzeigen, aber zeigen, wer übereinstimmt und wer nicht? oder einfach nur filtern?
Maxim Shoustin

Antworten:

144

Wie @Maxim Shoustin vorgeschlagen hat, ist der beste Weg, um das zu erreichen, was Sie wollen, die Verwendung eines benutzerdefinierten Filters.
Es gibt aber auch andere Möglichkeiten. Eine davon besteht darin, die ng-ifDirektive für dasselbe Element zu verwenden, in das Sie die ng-repeatDirektive eingefügt haben (auch hier ist der Plunker ):

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

Dies kann aus ästhetischer Sicht einen kleinen Nachteil darstellen, hat jedoch den großen Vorteil, dass Ihre Filterung auf einer Regel basieren kann, die nicht so eng an das playersArray gekoppelt ist und auf andere Daten im Anwendungsbereich Ihrer App problemlos zugreifen kann:

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

Update
Wie bereits erwähnt, ist dies eine der Lösungen für diese Art von Problem und kann Ihren Anforderungen entsprechen oder nicht.
Wie in den Kommentaren ausgeführt, ng-ifhandelt es sich um eine Richtlinie, die tatsächlich bedeutet, dass im Hintergrund möglicherweise mehr Dinge ausgeführt werden, als Sie erwarten.
Erstellt beispielsweise ng-if einen neuen Bereich aus dem übergeordneten Bereich :

Der in ngIf erstellte Bereich erbt mithilfe der prototypischen Vererbung von seinem übergeordneten Bereich.

Dies wirkt sich normalerweise nicht auf das normale Verhalten aus. Um jedoch unerwartete Fälle zu vermeiden, sollten Sie dies vor der Implementierung berücksichtigen.

gion_13
quelle
Dies war genau das, wonach ich suchte. Ich wusste, dass es einen kurzen und süßen Weg geben musste, um es ohne den benutzerdefinierten Filter zu tun. Vielen Dank!
aron.duby
Hinweis: Es gibt einige Bereichsverhalten von ng-if, wenn dies schwierig sein kann. Ich habe diese Methode ausprobiert und sie hat an anderer Stelle Probleme verursacht. Ich habe nämlich eine "Watcher" -Richtlinie, die ein Ereignis sendet, wenn der Repeater fertig ist. Nach dem Hinzufügen des ng-if zu diesem Repeater wurde dieses Ereignis nicht mehr ausgelöst. Ein benutzerdefinierter Filter ist möglicherweise der sauberste Weg.
Claywhipkey
@claywhipkey Sie haben Recht, der sauberste Weg ist die Verwendung eines Filters, aber das ist nicht für alle Fälle geeignet. Wie auch immer, danke für den Kommentar und Sie können sehen, dass ich in der Antwort ein Heads-up- Update hinzugefügt habe , um alle auf die Auswirkungen der Verwendung einer Direktive zum Filtern von Daten aufmerksam zu machen.
gion_13
43

Ich weiß , dass dies eine alte, aber falls jemand würde für eine andere mögliche Lösung aussehen, hier ist ein weiterer Weg , um diese zu lösen - Verwendung Standardfilterfunktionalität:

Objekt: Ein Musterobjekt kann verwendet werden, um bestimmte Eigenschaften von Objekten zu filtern, die im Array enthalten sind. Beispiel: Das Prädikat {name: "M", phone: "1"} gibt ein Array von Elementen zurück, deren Eigenschaftsname "M" und dessen Eigenschaftstelefon "1" enthält. ... Das Prädikat kann negiert werden, indem dem String! Vorangestellt wird. Beispiel: Das Prädikat {name: "! M"} gibt ein Array von Elementen zurück, deren Eigenschaftsname nicht "M" enthält.

Für das TS-Beispiel sollte so etwas also funktionieren:

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

Keine Notwendigkeit, benutzerdefinierte Filter zu schreiben, keine Notwendigkeit, ng-ifmit dem neuen Bereich zu verwenden.

Ilya Luzyanin
quelle
Einfach auf den Punkt. Kein benutzerdefinierter Filter oder neuer Bereich, der vom Autor erstellt wurde, wurde angegeben. Perfekt zum Überspringen eines einzelnen Werts in einer Liste.
mbokil
Ich denke, Sie müssen den 'Spieler' in 'player.name_key' weglassen - also wäre es im obigen Beispiel nur "{name_key: '! FirstPerson'}".
Smithml
Ich konnte Angular nie dazu bringen, mit leeren Tasten gut zu spielen. Gibt es einen Trick, um die eingebauten Filter für das Äquivalent von zu verwenden player in players | filter: { name_key: '' }? Diese spezielle Richtlinie entspricht nicht nur Spielern ohne / eines Leerzeichens name_key. Die Umkehrung, name_key: '!'mit der ein Spieler mit einem nicht leeren Spieler ausgewählt werden soll, name_keyfunktioniert ebenfalls nicht.
Eric L.
Sie können diese Antwort überprüfen .
Ilya Luzyanin
4
Beachten Sie, dass dies nur mit Arrays funktioniert, nicht mit Objekteigenschaften in einem Fall wieng-repeat="(key, val) in player"
David Diez
19

Sie können beim Implementieren einen benutzerdefinierten Filter verwenden ng-repeat. Etwas wie:

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

Demo Plunker

Maxim Shoustin
quelle
Vielen Dank für die Arbeit, die Sie in diese Sache gesteckt haben. Es ist definitiv richtig, aber am Ende hatte ich die einfache Antwort von @ gion_13 im Code, also dachte ich mir, ich sollte seine Antwort besser als akzeptierte Antwort
markieren