0

material_projectsまたはproject_servicesのいずれかを含むプロジェクトapiがあります。私はどちらか一方をどのように表示するのか混乱しています。もし私がmaterial_projectsを表示したら、私はproject_servicesを表示してはいけません。 project_servicesは、api内で空でなければなりません。特定のデータを角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

答えて

1

あなたがその制約を保証することができます場合は、単に両方のリストを反復することができるかもしれません。代替案として

<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> 

、あなたは条件付きで、どちらか一方を表示することがあります。

<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> 

か、のDTOが十分に類似している場合、あなたはビューロジックの多くを共有して検討することがあります。

<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:

プロパティの存在に基づいて異なるテーブルを使用する場合は、*ngIfステートメントを<table>要素または直下の子に移動することをお勧めします。これを行うには多くの方法があります

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

<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> 

コンポーネントコード:あなたのコメントに基づいて、次のようなものを試してみてください。もう1つのオプションは、テンプレート内でswitch文を使用するか、ビヘイビアを処理するために子(「ダミー」)コンポーネントを追加することです。

+0

実際、material_projectsとprojects_servicesのtheadsは異なっています。 material_projectsとproject_servicesのどちらでもない場合は、何も表示しません –

+0

material_projectsまたはproject_servicesのいずれもない場合のように3つの条件を作成するにはどうしたらいいですか? –

+0

@ GraySingh、3番目の条件を追加する必要がある場合、別の '* ngIf'構造ディレクティブを親ノードに追加することができます。編集を参照してください。 Angularの同じ問題を解決する方法はたくさんあるので、このコンポーネントを書くための多くの代替ソリューションがあります。また、プロジェクト表示のようなものをサブコンポーネントに抽象化することも考えられます。そのような小さなダミーコンポーネントにコンテンツを分割することは、 '* ngFor'ディレクティブの内容の共通パターンです。 –

関連する問題