kątowe ng-powtarzanie pomija element, jeśli pasuje do wyrażenia


91

Szukam sposobu, aby w zasadzie powiedzieć Angularowi, aby pominął element w powtórzeniu ng, jeśli pasuje do wyrażenia, w zasadzie continue;

W kontrolerze:

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

Teraz w moim szablonie chcę pokazać wszystkim, którzy nie pasują name_key='FirstPerson'. Pomyślałem, że to filtry, więc skonfigurowałem Plunkra, aby się nim bawić, ale nie miałem szczęścia. Plunkr Attempt


Próbuję zrozumieć: czy chcesz pokazać wszystkie przedmioty, ale wskazać, kto pasuje, a kto nie? czy po prostu przefiltruj?
Maxim Shoustin

Odpowiedzi:


144

Jak zasugerował @Maxim Shoustin , najlepszym sposobem osiągnięcia tego, co chcesz, byłoby użycie niestandardowego filtra.
Ale są też inne sposoby, jednym z nich jest użycie ng-ifdyrektywy w tym samym elemencie, w którym umieściłeś ng-repeatdyrektywę (również, tutaj jest plunker ):

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

Z estetycznego punktu widzenia może to stanowić niewielką wadę, ale ma tę główną zaletę, że filtrowanie może opierać się na regule, która nie jest tak ściśle powiązana z playerstablicą i może łatwo uzyskać dostęp do innych danych w zakresie aplikacji:

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

Aktualizacja
Jak wspomniano, jest to jedno z rozwiązań tego rodzaju problemu i może, ale nie musi, odpowiadać Twoim potrzebom.
Jak wskazano w komentarzach, ng-ifjest to dyrektywa, co w rzeczywistości oznacza, że ​​może zrobić więcej rzeczy w tle, niż można by się spodziewać.
Na przykład ng-if tworzy nowy zakres z jego rodzica :

Zakres utworzony w ngIf dziedziczy po swoim zakresie nadrzędnym przy użyciu dziedziczenia prototypowego.

Zwykle nie wpływa to na normalne zachowanie, ale aby zapobiec nieoczekiwanym przypadkom, należy o tym pamiętać przed wdrożeniem.


to było dokładnie to, czego szukałem, wiedziałem, że musi być jakiś krótki i słodki sposób na zrobienie tego bez niestandardowego filtra. Dzięki!
aron.duby,

Uwaga: istnieją pewne zachowania zakresu ng-if, które mogą być trudne. Wypróbowałem tę metodę i spowodowało to problemy w innych miejscach. Mianowicie mam dyrektywę "watcher", która nadaje zdarzenie, gdy repeater jest skończony. Po dodaniu ng-if do tego repeatera nie odpalało już tego zdarzenia. Własny filtr może być najczystszym rozwiązaniem.
claywhipkey

@claywhipkey masz rację, najczystszym sposobem jest użycie filtra, ale nie jest to odpowiednie dla wszystkich przypadków. W każdym razie dziękuję za komentarz i widzicie, że dodałem do odpowiedzi aktualizację heads-up, aby każdy był świadomy konsekwencji stosowania dyrektywy do filtrowania danych.
gion_13

43

Wiem, że to stara, ale gdyby ktoś szukał innego możliwego rozwiązania, oto inny sposób rozwiązania tego problemu - użyj standardowej funkcjonalności filtra :

Obiekt: obiekt wzorca może służyć do filtrowania określonych właściwości obiektów zawartych w szyku. Na przykład predykat {name: "M", phone: "1"} zwróci tablicę elementów, których nazwa właściwości zawiera "M", a nazwa właściwości zawiera "1". ... Predykat można zanegować, poprzedzając łańcuch znakiem!. Na przykład predykat {name: "! M"} zwróci tablicę elementów, których nazwa właściwości nie zawiera "M".

Więc dla przykładu TS powinno zrobić coś takiego:

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

Nie ma potrzeby pisania niestandardowych filtrów, nie ma potrzeby używania ng-ifich z nowym zakresem.


Proste do rzeczy. Nie utworzono żadnego filtra niestandardowego ani nowego zakresu, jak stwierdził autor. Idealny do pomijania pojedynczej wartości na liście.
mbokil

Myślę, że musisz pominąć 'player' z 'player.name_key' - więc w powyższym przykładzie będzie to po prostu „{name_key: '! FirstPerson'}”.
smithml

Nigdy nie udało mi się zmusić Angulara do ładnej gry z pustymi klawiszami. Czy jest jakaś sztuczka polegająca na użyciu wbudowanych filtrów jako odpowiednika player in players | filter: { name_key: '' }? Ta konkretna dyrektywa nie będzie dotyczyła tylko graczy bez pustego pola name_key. Odwrotność, która name_key: '!'ma na celu wybranie dowolnego gracza z niepustym, name_keyrównież nie zadziała.
Eric L.,

Możesz sprawdzić odpowiedź.
Ilya Luzyanin

4
Uważaj, to działa tylko z tablicami, a nie z właściwościami obiektów w przypadku takim jakng-repeat="(key, val) in player"
David Diez

19

Podczas implementacji możesz użyć niestandardowego filtru ng-repeat. Coś jak:

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

Próbny Plunker


Dzięki za pracę, którą w to włożyłeś. Jest zdecydowanie poprawna, ale skończyło się na łatwości odpowiedzi @ gion_13 w kodzie, więc pomyślałem, że lepiej oznaczyć jego jako zaakceptowaną odpowiedź
aron.duby.
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.