2017-12-20 3 views
0

Ich arbeite an einem eckigen 4 Projekt einen JSON über einen Dienst aufrufen, funktioniert alles sehr gut, nur für eine einzige Sache, mein JSON hat die folgende vereinfachte Struktur für das Verständnis des Problems:iterieren Elemente eines JSON mit * ngFor nur wenn sie eine Bedingung erfüllt

{ 
    "animals" [ 

    { 
    "name" : "dog" 
    "subgroup": "vertebrate" 
    "class" : "mammal" 
    }, 
    { 
    "name" : "pig" 
    "subgroup": "vertebrate" 
    "class" : "mammal" 
    }, 
    { 
    "name" : "cat" 
    "subgroup": "vertebrate" 
    "class" : "mammal" 
    }, 
    { 
    "name" : "snake" 
    "subgroup": "vertebrate" 
    "class" : "reptile" 
    }, 
    { 
    "name" : "lizzard" 
    "subgroup": "vertebrate" 
    "class" : "reptile" 
    }, 
    { 
    "name" : "crocodile" 
    "subgroup": "vertebrate" 
    "class" : "reptile" 
    }, 
] 
} 

und ich nur die Objekte mit der "Klasse" wiederholen will: "reptil"

machte ich diese Struktur:

<div class="col-12 mb-3" *ngFor="let reptiles of animals"> 
    <div *ngIf = "reptiles.class == reptile"> 
     <div class="row"> 
     <div class="col-12"> 
      <h5 class="py-3 bg-dark text-white pl-3 mx-0 mb-3">{{reptiles.name}}</h5> 
      <p class="py-3 bg-dark text-white font-weight-light pl-3 m-0">{{reptiles.class}}</p> 
     </div> 
     </div> 
    </div> 
    </div> 

bu t, was passiert, ist, dass es drei der Säugetiere leer

<div class="col-12 mb-3" *ngFor="let reptiles of animals"> 
</div> 

entsprechenden iteriert, und ich möchte, dass Objekte überhaupt nicht wiederholen, ich nur die Objekte mit der Klasse „Reptil“ iterieren wollen. wie kann ich das erreichen?

Antwort

1

helfen Ich denke, dass Sie dieses solution

filtern, dass nur nach Klasse Eigenschaft verwenden können:

filterItemsOfType(type){ 
    return this.items.filter(x => x.class == type); 
} 

Prost,

@carlosrojas_o

2

Die einfache Lösung ist ng-container anstelle eines div zu verwenden iterieren:

<ng-container *ngFor="let reptiles of animals"> 
    <div class="col-12 mb-3" *ngIf="reptiles.class == reptile"> 
     <div> 
      <!-- ... --> 
     </div> 
    </div> 
</ng-container> 

Natürlich ist die Vorlage noch Iterierten über diese Einträge jetzt, aber es wird für sie alle DOM-Knoten überhaupt nicht schaffen (die Magie von ng-container).

Möglicherweise ein besseres fix wäre stattdessen in Ihrer Komponente zu filtern und passieren nur die Daten, die Sie auf die Vorlage angezeigt werden sollen:

// In your controller after receiving the animals data: 
this.reptiles = this.animals.filter(a => a.class === "reptile"); 

// Template 
<div *ngFor="let reptile of reptiles">...</div> 

Sie können auch ein filterBy Rohr schreiben oder eine aus einer bestehenden Bibliothek nehmen wie zB ngx-pipes. Aber Vorsicht, dass Angular entmutigt, dass es leicht zu einer Performance-Falle wird.

+1

'ngFor' sollte auf' ng-container' geschrieben werden oder es wird zur Folge haben, in gleiche Problem – Dhyey

+0

@Dhyey Du hast Recht. Fest, danke. :-) –

+0

Die einfache Lösung hat nicht funktioniert, es iteriert immer noch die leeren divs der Säugetiere, weil der Zustand des ng-Containers nach den Iterationen angewendet wird, iteriert alle Objekte zuerst und wendet dann die Bedingung an, um zu zeigen oder nicht um den ng-container zu zeigen, wie könnte ich diese daten in der komponente filtern? Ich habe vor ein paar Monaten angefangen mit eckigen zu arbeiten und es gibt eine Menge Dinge, die ich immer noch nicht kenne. –

0

Sie müssen nur Ihre Daten in der Komponente so filtern:

this.filteredAnimals = this.animals.filter(animal => animal.class === "reptile"); // now use filteredAnimals in html template 

Hoffe, dass es

Verwandte Themen