0

Ich habe eine Projekt-API, die entweder material_projects oder project_services enthält. Ich bin verwirrt, wie ich einen von ihnen anzeigen würde. Wenn ich material_projects anzeige, darf ich project_services nicht anzeigen. project_services muss in der API leer sein.Spezifische Daten in Angular anzeigen 2/4

getAllProjects() { 
    this.subscription = this.projectsService.getAll() 
     .subscribe(
     (data:any) => { 
      this.projects = data.projects; 
      console.log(data); 
     }, 
     error => { 
      console.log(error); 
     }); 
    } 

html

<div class="card-block" *ngFor="let project of projects | search : searchBOM"> 
    <h2 class="proj-name">{{ project.name | titlecase }} </h2> 
    <table class="table table-bordered table-striped"> 
    <thead> 
     <tr> 
     <th>Material SKU</th> 
     <th>Material Name</th> 
     <th>Unit</th> 
     </tr> 
    </thead> 
    <tbody> 
     <tr *ngFor="let innerItem of project.material_projects"> 
     <td>{{innerItem.material.sku}}</td> 
     <td>{{innerItem.material.name}}</td> 
     <td>{{innerItem.unit}}</td> 
     </tr> 
    </tbody> 
    </table> 
</div> 

enter image description here

Antwort

1

Wenn Sie diese Einschränkung garantieren können, dann können Sie in der Lage sein, beide Listen einfach durchlaufen.

<tbody> 
    <ng-container *ngIf="project.material_projects.length > 0; then #materialProjectsRows; else #projectServicesRows"></ng-container> 
    <ng-template #materialProjectsRows> 
    <tr *ngFor="let innerItem of project.material_projects"> 
     <td>{{innerItem.material.sku}}</td> 
     <td>{{innerItem.material.name}}</td> 
     <td>{{innerItem.unit}}</td> 
    </tr> 
    </ng-template> 
    <ng-template #projectServicesRows> 
    <tr *ngFor="let innerItem of project.projectServices"> 
     <td>{{innerItem.service.sku}}</td> 
     <td>{{innerItem.service.name}}</td> 
     <td>{{innerItem.unit}}</td> 
    </tr> 
    </ng-template> 
</tbody> 

Oder, wenn die DTOs sind ähnlich genug, können Sie prüfen, mehr der Ansicht Logik teilen:

<tbody> 
    <tr *ngFor="let innerItem of project.material_projects"> 
    <td>{{innerItem.material.sku}}</td> 
    <td>{{innerItem.material.name}}</td> 
    <td>{{innerItem.unit}}</td> 
    </tr> 
    <tr *ngFor="let innerItem of project.project_services"> 
    <td>{{innerItem.service.sku}}</td> 
    <td>{{innerItem.service.name}}</td> 
    <td>{{innerItem.unit}}</td> 
    </tr> 
</tbody> 

Als Alternative können Sie bedingt das eine oder andere Anzeige

<tbody> 
    <!-- You may want to perform the concatenation inside of the view model for additional clarity --> 
    <tr *ngFor="let innerItem of project.material_projects.concat(project.project_services)"> 
    <td>{{(innerItem.material || innerItem.service).sku}}</td> 
    <td>{{(innerItem.material || innerItem.service).name}}</td> 
    <td>{{innerItem.unit}}</td> 
    </tr> 
</tbody> 

EDIT:

Wenn Sie auf der Existenz von Grundstücken anhand verschiedene Tabellen verwenden mögen, dann sollten Sie Ihre *ngIf Anweisungen bis zum <table> Elemente oder ein sofortigen Kind bewegen.

<div class="card-block" *ngFor="let project of projects | search : searchBOM"> 
    <ng-container *ngIf="getProjectType(project)"> 
    <h2 class="proj-name">{{ project.name | titlecase }}</h2> 

    <table *ngIf="getProjectType(project) === 'material'" class="table table-bordered table-striped"> 
     <thead> 
     <tr> 
      <th>Material SKU</th> 
      <th>Material Name</th> 
      <th>Unit</th> 
     </tr> 
     </thead> 
     <tbody> 
     <tr *ngFor="let innerItem of project.material_projects"> 
      <td>{{innerItem.material.sku}}</td> 
      <td>{{innerItem.material.name}}</td> 
      <td>{{innerItem.unit}}</td> 
     </tr> 
     </tbody> 
    </table> 

    <table *ngIf="getProjectType(project) === 'services'" class="table table-bordered table-striped"> 
     <thead> 
     <tr> 
      <th>Project SKU</th> 
      <th>Project Name</th> 
      <th>Unit</th> 
     </tr> 
     </thead> 
     <tbody> 
     <tr *ngFor="let innerItem of project.project_services"> 
      <td>{{innerItem.project.sku}}</td> 
      <td>{{innerItem.project.name}}</td> 
      <td>{{innerItem.unit}}</td> 
     </tr> 
     </tbody> 
    </table> 

    </ng-container> 
</div> 

Komponentencode:

export class ProjectComponent { 
    ... 
    public getProjectType(project: Project): 'material' | 'services' | null { 
     return project.material_projects.length > 0 ? 'material' 
      : project.project_services.length > 0 ? 'services' 
      : null; 
    } 
    ... 
} 

Es gibt viele Möglichkeiten, dies zu tun, basierend auf Ihre Kommentare, können Sie so etwas wie die folgenden versuchen. Eine andere Option wäre, eine switch-Anweisung in Ihrer Vorlage zu verwenden oder zusätzliche untergeordnete ("Dummy") Komponenten hinzuzufügen, um das Verhalten zu behandeln. Eigentlich

+0

haben die material_projects und projects_services verschiedene theads. und wenn sie weder material_projects noch project_services sind, dann zeige nichts an –

+0

Wie kannst du 3 Bedingungen erstellen, wenn es weder material_projects noch project_services gibt, dann zeige dieses bestimmte Projekt nicht an? –

+0

@GraySingh, wenn Sie eine dritte Bedingung hinzufügen müssen, können Sie einem übergeordneten Knoten eine weitere '* ngIf'-Strukturanweisung hinzufügen. Siehe Änderungen. Es gibt viele Möglichkeiten, das gleiche Problem in Angular zu lösen, daher gibt es viele alternative Lösungen zum Schreiben dieser Komponente. Sie können auch in Betracht ziehen, Dinge (wie die Projektanzeige) in Unterkomponenten zu abstrahieren. Das Teilen von Inhalt in kleinere Dummy-Komponenten ist ein übliches Muster für den Inhalt von '* ngFor'-Direktiven. –

Verwandte Themen