角材料自动完成中多次调用该方法

时间:2019-09-09 15:13:06

标签: css angular autocomplete angular-material angular7

我们已经使用角度材料自动完成创建了一个组件。为了显示选项,我们正在遍历 51个对象的数组。我正在将CSS类应用于已选择的选项。 isAccountingTypeSelected 方法确定是否选择了该选项。 该方法被称为 51 * 28 = 1428次。我似乎不明白原因?应该只叫它 51次,不是吗?

<mat-form-field class="full-width">
  <input type="text" matInput #autoCompleteInput [formControl]="autocompleteForm" [matAutocomplete]="auto" placeholder="Choose Accounting Type" aria-label="Number">

  <span matSuffix class="close-icon hover" *ngIf="autoCompleteInput.value" (click)="clearAll($event)"></span>
  <span matSuffix class="arrow-drop-down-icon hover" (click)="openPanel()"></span>

  <mat-autocomplete #auto="matAutocomplete" (optionSelected)="accountingTypeSelected($event)">
    <mat-option *ngFor="let accountingType of filteredAccountingTypes | async" [value]="accountingType.code">
      <span class="accounting-type-options" [class.selected]="isAccountingTypeSelected(accountingType.code)">
        {{ accountingType.name + ' (' + accountingType.code + ')' }}
      </span>
    </mat-option>
  </mat-autocomplete>
</mat-form-field>

isAccountingTypeSelected(code: string): boolean {
  console.log('I was called');
  if (this.selectedAccountingTypes.find((accountingType: AccountingType) => accountingType.code === code)) {
    return true;
  }

  return false;
}

4 个答案:

答案 0 :(得分:2)

Angular将在每次检查更改时评估该表达式,在您的情况下,这可能是将CSS添加到您的span元素中。 在for循环中从模板调用方法不是最佳方法,因为它们经常被调用。您应该将结果存储在一个属性中,然后绑定到该属性。

答案 1 :(得分:2)

这是一个绑定问题。 Angular检查结果值的次数更多。您可以尝试使用ChangeDetectionStrategy.CheckOnce

答案 2 :(得分:2)

Angular多次使用changedetection生命周期来检查[class.selected]或ngClass函数是否已更改。如果使用函数,它将多次调用。因此,不建议在绑定时使用函数,而应该在component.ts文件中计算值,然后将值绑定到ngClass或[class]。

示例:Stackblitz

N.B:我们知道,更改选择的值会触发事件更改,我们可以对其进行计算并将计算结果附加到[class.my-class]或ngClass。

答案 3 :(得分:0)

您的ngFor循环需要跟踪特定的ID,因此它不会一无所获。试试这个:

<mat-option *ngFor="let accountingType of filteredAccountingTypes | async; trackBy: trackByCode"[value]="accountingType.code">
</mat-option>

然后添加此功能:

trackByCode(index: number, accountingType: yourType): string {
    return accountingType.code;
}