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);
};
我正在使用 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);
};