Angular FormControl 在设置值时不更新视图

Angular FormControl does not update view when setValue

我正在使用 Angular Material 构建通用 select 或组件 。手动设置值时它工作正常但是,如果我从打字稿更新表单值,视图不会反映该更改。

selector.component.html

<mat-form-field appearance="standard">
  <mat-label>{{ label }}</mat-label>
  <mat-select
    [formControl]="formControl"
    (valueChange)="onChange($event)"
    multiple
  >
    <mat-select-trigger>
      {{ !!selectedData.length ? selectedData[0][elementLabel] : '' }}
      <span *ngIf="selectedData.length > 1" class="additional-selection">
        (+{{ selectedData.length - 1 }}
        {{ selectedData?.length === 2 ? 'other' : 'others' }})
      </span>
    </mat-select-trigger>
    <mat-option
      *ngFor="let element of data; trackBy: trackByFunction"
      [value]="element"
      >{{ element[elementLabel] }}</mat-option
    >
  </mat-select>
</mat-form-field>

selector.component.ts

import {
  ChangeDetectionStrategy,
  Component,
  EventEmitter,
  Input,
  Output,
} from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
  selector: 'selector',
  templateUrl: './selector.component.html',
  styleUrls: ['./selector.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SelectorComponent {
  @Input() data: any[] = [];
  @Input() set init(value: any[]) {
    this.selectedData = value;
  }
  @Input() label: string = '';
  @Input() elementLabel: string = '';
  @Output() onChangeEvent: EventEmitter<any[]> = new EventEmitter();
  selectionDisplayText = '';
  formControl = new FormControl([]);

  get selectedData(): any[] {
    return this.formControl.value;
  }

  set selectedData(data: any[]) {
    this.formControl.setValue(data);
  }

  trackByFunction(item: any): string {
    return item[this.elementLabel];
  }

  onChange = (data: any[]) => {
    this.selectedData = data;
    this.onChangeEvent.emit(this.selectedData);
  };
}

当我尝试从父组件(使用 init 输入)更新 select 值时,代码到达 set selectedData 方法并且 formControl 值设置正常,但视图显示空 select。我错过了什么?

谢谢

我找到了解决办法。

我没有使用 formControl(这使事情变得复杂),而是使用 ngModel 来设置 mat-select 数据。

<mat-select
    (valueChange)="onChange($event)"
    [ngModel]="selection"
    [compareWith]="compareFn"
    multiple
>

我的 问题mat-select 通过 reference () 比较对象,所以我需要添加 compareWith 函数以基于 属性 进行比较。就我而言:

compareFn = (obj1: any, obj2: any) => {
    return obj1[this.elementLabel] === obj2[this.elementLabel];
};

并更新 onChange 函数,以便更新 selection

onChange = (data: any[]) => {
  const value = this.transform(data);
  this.selection = value;
  this.onChangeEvent.emit(value);
};