angular ng-repeat salta un elemento se corrisponde all'espressione


91

Sto cercando un modo per dire fondamentalmente ad angular di saltare un elemento in un ng-repeat se corrisponde a un'espressione, fondamentalmente continue;

Nel controller:

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

Ora nel mio modello voglio mostrare a tutti quelli che non corrispondono name_key='FirstPerson'. Ho pensato che dovessero essere filtri, quindi ho impostato un Plunkr per giocarci ma non ho avuto fortuna. Plunkr Attempt


Cerco di capire: vuoi mostrare tutti gli elementi ma punto chi corrisponde e chi no? o solo filtro?
Maxim Shoustin

Risposte:


144

Come suggerito da @Maxim Shoustin , il modo migliore per ottenere ciò che desideri sarebbe utilizzare un filtro personalizzato.
Ma ci sono altri modi, uno di questi è usare la ng-ifdirettiva sullo stesso elemento in cui hai inserito la ng-repeatdirettiva (inoltre, ecco il plunker ):

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

Questo può presentare un piccolo svantaggio dal punto di vista estetico, ma ha un grande vantaggio che il tuo filtro potrebbe essere basato su una regola che non è così strettamente accoppiata playersall'array e che può accedere facilmente ad altri dati nell'ambito della tua app:

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

Aggiorna
Come affermato, questa è una delle soluzioni per questo tipo di problema e può o non può soddisfare le tue esigenze.
Come sottolineato nei commenti, ng-ifè una direttiva, il che in realtà significa che potrebbe fare più cose in background di quanto ci si potrebbe aspettare.
Ad esempio, ng-if crea un nuovo ambito dal suo genitore :

L'ambito creato all'interno di ngIf eredita dall'ambito padre utilizzando l'ereditarietà prototipale.

Questo di solito non influisce sul comportamento normale, ma per prevenire casi imprevisti, dovresti tenerlo a mente prima di implementarlo.


questo era esattamente quello che stavo cercando, sapevo che doveva esserci un modo breve e dolce per farlo senza il filtro personalizzato. Grazie!
aron.duby

Nota: ci sono alcuni comportamenti dell'ambito di ng-if che possono essere complicati. Ho provato questo metodo e ha causato problemi altrove. Vale a dire, ho una direttiva "watcher" che trasmette un evento quando il ripetitore è finito. Dopo aver aggiunto ng-if a questo ripetitore, non ha più attivato quell'evento. Un filtro personalizzato potrebbe effettivamente essere il modo più pulito da percorrere.
claywhipkey

@claywhipkey hai ragione, il modo più pulito è usare un filtro, ma non è adatto a tutti i casi. Ad ogni modo, grazie per il commento e puoi vedere che ho aggiunto un aggiornamento in testa alla risposta solo per rendere chiunque consapevole delle implicazioni dell'utilizzo di una direttiva per il filtraggio dei dati.
gion_13

43

So che questo è vecchio, ma nel caso in cui qualcuno cercasse un'altra possibile soluzione, ecco un altro modo per risolverlo: usa la funzionalità di filtro standard :

Oggetto: un oggetto modello può essere utilizzato per filtrare proprietà specifiche su oggetti contenuti da un array. Ad esempio, il predicato {nome: "M", telefono: "1"} restituirà un array di elementi il ​​cui nome di proprietà contiene "M" e telefono di proprietà contenente "1". ... Il predicato può essere negato anteponendo alla stringa!. Ad esempio, il predicato {name: "! M"} restituirà un array di elementi che hanno un nome di proprietà che non contiene "M".

Quindi, per l'esempio TS, qualcosa del genere dovrebbe funzionare:

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

Non è necessario scrivere filtri personalizzati, non è necessario utilizzarli ng-ifcon il nuovo ambito.


Semplice al punto. Nessun filtro personalizzato o nuovo ambito creato come dichiarato dall'autore. Perfetto per saltare un singolo valore in un elenco.
mbokil

Penso che tu debba omettere "player" da "player.name_key", quindi nell'esempio precedente sarebbe solo "{name_key: '! FirstPerson'}".
smithml

Non sono mai riuscito a convincere Angular a suonare bene con le chiavi vuote. C'è una sorta di trucco per utilizzare i filtri incorporati per l'equivalente di player in players | filter: { name_key: '' }? Quella particolare direttiva non corrisponderà solo ai giocatori senza / un vuoto name_key. Anche l'inverso, name_key: '!'inteso a selezionare qualsiasi giocatore con un non vuoto name_key, non funzionerà.
Eric L.

Puoi controllare questa risposta.
Ilya Luzyanin

4
Attenzione che funziona solo con gli array, non con le proprietà degli oggetti in un caso comeng-repeat="(key, val) in player"
David Diez

19

È possibile utilizzare un filtro personalizzato durante l'implementazione ng-repeat. Qualcosa di simile a:

 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


Grazie per il lavoro che ci metti. È decisamente corretto, ma ho finito per usare la facilità della risposta @ gion_13 nel codice, quindi ho pensato di contrassegnare meglio la sua come risposta accettata
aron.duby
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.