方法在角度材料自动完成中被多次调用

Posted

技术标签:

【中文标题】方法在角度材料自动完成中被多次调用【英文标题】:method gets called multiple times in angular material autocomplete 【发布时间】:2020-01-11 09:14:48 【问题描述】:

我们使用 Angular 材料autocomplete 创建了一个组件。为了显示选项,我们遍历了一个 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;

【问题讨论】:

【参考方案1】:

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

示例:Stackblitz

N.B:我们知道当我们改变选择的值时会触发一个事件改变,我们可以计算它并将计算结果附加到 [class.my-class] 或 ngClass。

【讨论】:

请查看 stackblitz 以获取类似您的示例【参考方案2】:

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

【讨论】:

【参考方案3】:

这是一个绑定问题。 Angular 检查更多次结果值。你可以试试ChangeDetectionStrategy.CheckOnce

【讨论】:

【参考方案4】:

您的 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;

【讨论】:

以上是关于方法在角度材料自动完成中被多次调用的主要内容,如果未能解决你的问题,请参考以下文章

角度材料自动完成 - 如何防止键盘输入以在建议面板中选择一个选项

材料角度自动完成:选择选项后如何在屏幕中保留垫子选项?

如何在角度材料 2 中使用 mat-chip 和自动完成来保存选定的对象

如何使用 CdkScrollable 检测角度材料 2 自动完成列表上的滚动事件

角度材料数据表 - 如何为具有提前类型/自动完成搜索的列设置 filterPredicate?

如何将 onchange 与自动完成材料 ui 一起使用?