Угловая реактивная форма patchValue() не заполняет ввод, связанный с автозаполнением mat
Я пытаюсь повторно заполнить вход, который использует автозаполнение мат. Однако всякий раз, когда я отправляю значение с this.optionForm.patchValue({selectedOption: 'my value'})
результаты не отображаются в графическом интерфейсе. Если я console.log()
Я ясно вижу значение установлено. Я не уверен, что проблема связана с тем фактом, что я иногда устанавливаю объект в поле, а иногда - просто строку? Но я хотел бы иметь возможность повторно заполнить ввод результатами и отобразить их соответствующим образом. Независимо от того, как я стараюсь, я не могу получить результаты для отображения.
Ниже мой компонент сокращен только до рассматриваемого ввода и мой Observable, который извлекает результаты для mat-autocomplete
, Они отлично работают при первом использовании формы.
// component.html
<mat-form-field>
<mat-label>Option Object</mat-label>
<input type="text" matInput formControlName="selectedOption" required
[matAutocomplete]="autoGroup">
<mat-autocomplete #autoGroup="matAutocomplete"
(optionSelected)="updateOptionInfo($event.option.value)"
[displayWith]="displayFn">
<mat-option *ngFor="let result of resultOptions | async" [value]="result">
<span>{{result}}</span>
</mat-option>
</mat-autocomplete>
// component.ts
this.resultOptions = this.optionForm.get('selectedOption').valueChanges
.pipe(
debounceTime(300),
switchMap(value => {
if (value === '') {
this.clearProviderInfo();
return of(null);
}
if (value !== '' && ((typeof value) !== 'object')) {
return this.optionService.fetchAndFilterOptions(value)
.pipe(
catchError((e) => {
console.error(e);
return of([]); // empty list on error
})
);
} else {
return of(null);
}
})
);
Любая помощь будет оценена!
2 ответа
Я создал стек, чтобы воспроизвести проблему:
https://stackblitz.com/edit/material-6-gh3rmt?file=app/app.component.ts
При этом я понимаю, в чем проблема! Имея функцию отображения, возвращающую некоторое свойство объекта, она явно отображает пустую строку. Таким образом, объект устанавливается и может быть виден в форме, но поскольку я использовал пользовательскую функцию отображения, он запускается свойством null в строке.
Надеюсь, я смогу помочь другим людям, которые могут столкнуться с этой проблемой в будущем!
Чтобы конкретизировать это решение:
displayFn(x) {
return x.name; // if name doesn't exist this will obviously return null!
}
Таким образом, исправление заключается в создании резервной копии на тот случай, если выбранное не является объектом с .name
имущество:
if ((typeof x) === 'string') {
return x;
}
return x ? x.name : undefined;
Подход 1:
использование setTimeout
Для достижения желаемого результата используйте следующее:
setTimeout(()=>{
this.optionForm.patchValue({selectedOption: 'test'});
}, 0);
Подход 2:
Этот подход работает без async
//-----in component.html file, without async-------
*ngFor="let result of resultOptions"
// -------in component.ts file---------
this.optionForm.get('selectedOption').valueChanges
.pipe(
debounceTime(300),
switchMap(value => {
if (value === '') {
this.clearInfo();
return of(null);
}
if (value !== '' && ((typeof value) !== 'object')) {
return of(this.pretendOptions);
} else {
return of(null);
}
})
).subscribe(e=>this.resultOptions = e);
//--- value is updated after subscribing to the `valueChanges`.
this.optionForm.patchValue({selectedOption: 'test'});