简体   繁体   English

ngIf在ng容器在垫子桌里面

[英]ngIf in ng-container inside mat-table

I am new to Angular. 我是Angular的新手。 I have a following problem: I need to display on a table only rows with status == "FINISHED". 我有以下问题:我只需要在表上显示状态==“完成”的行。 I understand why my code doesn't work the way I want, but can't get the right solution for me. 我了解为什么我的代码无法按我想要的方式工作,但无法为我找到正确的解决方案。

Here is the .ts file: 这是.ts文件:

import { Component, OnInit } from '@angular/core';

 import { TestCase } from '../test-cases/models/test-case.model';
 import { TestCaseService } from '../test-case.service';

@Component({
  selector: 'app-test-cases-view',
  templateUrl: './test-cases-view.component.html',
  styleUrls: ['./test-cases-view.component.css']
})
export class TestCasesViewComponent implements OnInit {
  testCases: TestCase[];
  displayedColumns: string[] = ['testCaseName', 'testCaseDescription','id','created','status', 'xls'];
  constructor(private testCaseService: TestCaseService) { }

  ngOnInit() {
    this.getTestCases();
  }

  postRequest(testCaseId: string):void {
    this.testCaseService.postTestResult(testCaseId);
  }

  getTestCases(): void {
    this.testCaseService.getTestCases()
      .subscribe(testCases => this.testCases = testCases);
  }

}

test-case.model.ts file: test-case.model.ts文件:

import { TestCaseParams } from './test-case-params.model';

export class TestCase {
  public testCaseName:string;
  public testCaseDescription:string;
  public parameters:TestCaseParams;
  public id:string;

  constructor () {
    this.parameters= new TestCaseParams();
  }
}

test-case-params.model.ts 测试用例参数

import { EditedVar } from './replacement.model';
import { FilterVar } from './filter.model';
import { OutputVar } from './output.model';

export class TestCaseParams {
  public appsCount: number;
  public algId: number;
  public product: string;
  public invokeConsolidation: boolean;
  public invokeProdStrategy: boolean;
  public filterVars: FilterVar[];
  public editedVars: EditedVar[];
  public outputVars: OutputVar[];
  public fromDate: Date;
  public toDate:Date;
}

replacement.model.ts: replace.model.ts:

export class EditedVar {
  public path:string;
  public value:string;
}

filter.model.ts: filter.model.ts:

export class FilterVar{
  public filter:string;
  public filterType:string;
  public filterValue:string;
  public varch:boolean;
}

output.model.ts: output.model.ts:

export class OutputVar {
  public path:string;
  public alias:string;
  public type:string;
}

Here is the html file that works: 这是有效的html文件:

<div id="view-component">
  <h2>Test Cases</h2>

  *some code just don't fit in the question*

    <ng-container matColumnDef="xls">
      <th mat-header-cell *matHeaderCellDef> Xls report </th>
      <td mat-cell *matCellDef="let testCase">
        <button *ngIf = "testCase.status == 'FINISHED'" (click)="postRequest(testCase.id)">Make Excel report</button>
      </td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
  </table>
</div>

Here is what I try to do: 这是我尝试做的事情:

<table mat-table [dataSource]="testCases" class="mat-elevation-z8">

    <ng-container *ngIf = "testCase.status == 'FINISHED'" matColumnDef="testCaseName">
      <th mat-header-cell *matHeaderCellDef> testCaseName </th>
      <td mat-cell *matCellDef="let testCase"> {{testCase.testCaseName}} </td>
    </ng-container>

    <ng-container *ngIf = "testCase.status == 'FINISHED'" matColumnDef="testCaseDescription">
      <th mat-header-cell *matHeaderCellDef> testCaseDescription </th>
      <td mat-cell *matCellDef="let testCase"> {{testCase.testCaseDescription}} </td>
    </ng-container>

    <ng-container *ngIf = "testCase.status == 'FINISHED'" matColumnDef="id">
      <th mat-header-cell *matHeaderCellDef> Report Id </th>
      <td mat-cell *matCellDef="let testCase"> {{testCase.id}} </td>
    </ng-container>

    <ng-container *ngIf = "testCase.status == 'FINISHED'" matColumnDef="created">
      <th mat-header-cell *matHeaderCellDef> Created </th>
      <td mat-cell *matCellDef="let testCase"> {{testCase.created | date: 'dd/MM/yyyy hh:mm:ss'}} </td>
    </ng-container>

    <ng-container *ngIf = "testCase.status == 'FINISHED'" matColumnDef="status">
      <th mat-header-cell *matHeaderCellDef> Status </th>
      <td mat-cell *matCellDef="let testCase"> {{testCase.status}} </td>
    </ng-container>

    <ng-container *ngIf = "testCase.status == 'FINISHED'" matColumnDef="xls">
      <th mat-header-cell *matHeaderCellDef> Xls report </th>
      <td mat-cell *matCellDef="let testCase">
        <button (click)="postRequest(testCase.id)">Make Excel report</button>
      </td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
  </table>

As you can see I don't want to display rows with any status that isn't equeal "FINISHED". 如您所见,我不想显示状态不等于“完成”的行。 For this code I get a following error: 对于此代码,我得到以下错误:

ERROR TypeError: Cannot read property 'status' of undefined at Object.eval [as updateDirectives] (TestCasesViewComponent.html:6) 错误TypeError:无法读取Object.eval上未定义的属性“状态” [作为updateDirectives](TestCasesViewComponent.html:6)

I understand that I need to place let testCase somewhere else, so it would be defined on the ng-container level, but I can't figure out where. 我了解我需要将let testCase放置在其他位置,因此它将在ng容器级别定义,但是我不知道在哪里。

That error is because testCase is undefined , and in javascript accessing properties (like testCase.status ) in an undefined object will always throw that error. 该错误是因为testCaseundefined ,并且在javascript中访问未定义对象中的属性(如testCase.status )将始终引发该错误。

But the reason testCase is undefined in the first place is because *ngIf will be run before the method getTestCases() 但是首先未定义testCase的原因是因为*ngIf将在方法getTestCases() 之前运行

You have two possible solutions: 您有两种可能的解决方案:

  1. Instantiate the object; 实例化对象;

  2. Use another *ngIf to check if testCase is undefined. 使用另一个* ngIf检查testCase是否未定义。

For example: 例如:

    <div *ngIf="testCase">
       <div *ngIf="testCase.status == 'FINISHED'">

       </div>
    </div>

In other words, you just need to be sure that testCase in not undefined when you access its properties in the *ngIf . 换句话说,当您在*ngIf访问其testCase的属性时,只需确保它没有未定义*ngIf

Rather than do the filtering at the mat-table level, you can filter the array that you get from the Observable and assign the filtered array as the data instead: 您可以过滤从Observable获得的数组,然后将过滤后的数组分配为数据,而不是在mat-table级别进行过滤:

getTestCases(): void {
  this.testCaseService.getTestCases()
    .subscribe(testCases => this.testCases = testCases.filter(({ status }) =>
      status === 'FINISHED',
  ));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM