Условие
Компонент таблицы - таблица с кнопкой создания / редактирования строки. При нажатии на любую из этих кнопок открывается тот же компонент диалога с полем ввода. Поле ввода - многоразовые микросхемы с автозаполнением компонент . Если пользователь нажимает «редактировать строку», указанные значения должны быть установлены в поле ввода как матовые фишки и оставаться доступными для редактирования (удалить фишку (ы) или добавить новую). Если выбрано «создать строку» - пустой ввод, пользователь может добавлять новые.
Проблема
Когда я открываю диалог редактирования, у меня есть значения из таблицы, установленные в поле ввода. Но с ним я получаю сообщение об ошибке:
ERROR TypeError: control.registerOnChange не является функцией
Существует связь между диалоговым компонентом и компонентом ввода, о чем я не могу понять. Я предполагаю, что проблема где-то в FormControl и ControlValueAccessor .
Код
dialog.component.ts:
this.fb.group({
*here are some working FormControls*,
managers: this.fb.array(this.someInterface.managers)
dialog.component. html:
<managers-auto-chips-selector
formControlName="managers">
</managers-auto-chips-selector>
input.component. html:
<mat-form-field appearance="outline">
<mat-label>Manager</mat-label>
<mat-chip-list #chipList>
<mat-chip
*ngFor="let item of selectedList"
[selectable]="selectable"
[removable]="removable"
(removed)="remove(item)">
{{item.name}}
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
</mat-chip>
<input matInput
placeholder="Manager"
#managerInput
[matAutocomplete]="autocomplete"
[formControl]="managerControl"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="add($event)">
</mat-chip-list>
<mat-autocomplete #autocomplete="matAutocomplete" (optionSelected)="selected($event)">
<mat-option *ngFor="let item of filteredList | async" [value]="item">
{{ item.name }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
input.component.ts (добавлено):
filteredList: Observable<Manager[]>;
list: Manager[] = []; <--- managers list filled from API
selectedList: Manager[] = [];
managerControl = new FormControl();
constructor( @Optional() @Self() public ngControl: NgControl) {
if (this.ngControl != null) {
this.ngControl.valueAccessor = this;
}
}
ngOnInit(): void {
this.filteredList = this.managerControl.valueChanges.pipe(
map((manager: string | null) => {
return manager ? this._filter(manager) :
this.list.slice();
})
);
this.getManagersList();
}
private _filter(value: any): any[] {
return this.list.filter(manager => {
if (typeof value === 'string') {
return manager.fio.toLowerCase().includes(value.toLowerCase());
} else {
return manager.fio.toLowerCase().includes(value.fio.toLowerCase());
}
});
}
add(event: MatChipInputEvent): void {
const input = event.input;
const value = event.value;
// Add our fruit
if ((value || '').trim()) {
const item = this.list.filter(manager => {
return manager.fio.toLowerCase().includes(value.toLowerCase());
});
if (item.length === 1) {
this.selectedList.push(item[0]);
}
}
// Reset the input value
if (input) {
input.value = '';
}
this.managerControl.setValue(null);
}
selected(event: MatAutocompleteSelectedEvent): void {
this.selectedList.push(event.option.value);
this.managerInput.nativeElement.value = '';
this.managerControl.setValue(null);
}
registerOnChange(fn: any): void {
}
registerOnTouched(fn: any): void {
}
writeValue(item: any): void {
this.selectedList = item;
}
У меня есть несколько предложений, куда двигаться дальше, но любое из них уводит меня от результата, который у меня есть на данный момент. По-прежнему:
1) В диалоговом компоненте. html formControlName
до formArrayName
. Если я это сделаю, ошибка не появится, но мои значения не установлены, и у меня пустой ввод.
2) В input.component.ts от managerControl = new FormControl()
до new FormArray([ ])
. Затем у меня появилось несколько (!) Сообщений об ошибках:
ERROR TypeError: control.registerOnChange не является функцией
3) Что-то, что нужно поместить в функцию registerOnChange
. Не могу понять.
4) Каким-то образом pu sh каждый FormControl от dialog.components.ts managers: this.fb.array(this.someInterface.managers)
до managerControl = new FormArray([]);
5) ???
Любые комментарии или советы приветствуется.
Более подробные объяснения, дополнительный код или скриншоты будут предоставлены по запросу.
Спасибо.