0

我有一个包含 material_projects 或 project_services 的项目 api。我对如何显示其中任何一个感到困惑。如果我显示 material_projects,那么我不能显示 project_services。project_services 在 api 中必须为空。

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>

在此处输入图像描述

4

1 回答 1

0

如果您可以保证该约束,那么您可以简单地遍历两个列表。

<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 语句,或添加额外的子(“虚拟”)组件来处理行为。

于 2017-10-20T16:41:41.280 回答