0

我有一個包含material_projects或project_services的項目api。我很困惑我將如何顯示其中一個。如果我顯示material_projects,那麼我不能顯示project_services。 project_services在api中必須是空的。在Angular 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> 

編輯:

如果您想根據屬性的存在使用不同的表格,那麼您需要將您的*ngIf語句移動到<table>元素或直接子元素。根據您的意見,您可以嘗試類似以下內容:

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

組件代碼:

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

有很多方法可以做到這一點。另一種選擇是在模板中使用switch語句,或者添加額外的子(「虛擬」)組件來處理行爲。

+0

其實,material_projects和projects_services有不同的角色。如果他們既不是material_projects和project_services那麼也不顯示任何東西 –

+0

如何做出3個條件,如沒有material_projects或project_services,那麼不顯示該特定項目? –

+0

@GraySingh,如果你需要添加第三個條件,那麼你可以添加另一個'* ngIf'結構指令給父節點。查看修改。在Angular中有很多方法可以解決同樣的問題,所以編寫這個組件的方法有很多。您也可以考慮將事物(如項目顯示)抽象爲子組件。將內容分隔成更小的虛擬組件是'* ngFor'指令內容的常見模式。 –