Angular Reactive Form patchValue() 不填充连接到 mat-autocomplete 的输入
Angular Reactive Form patchValue() doesn't fill input connected to mat-autocomplete
我正在尝试重新填充使用 mat-autocomplete 的输入。但是,每当我发送带有 this.optionForm.patchValue({selectedOption: 'my value'})
的值时,结果都不会显示在 GUI 中。如果我 console.log()
我可以清楚地看到设置的值。我不确定这个问题是否与我有时将一个对象设置到字段中而其他时候只设置一个字符串这一事实有关?但我希望能够用结果重新填充输入并适当地显示它。无论我如何尝试,我似乎都无法显示结果。
下面是我的组件,仅包含有问题的输入和正在为 mat-autocomplete
获取结果的 Observable。这些在第一次使用表单时工作正常。
// 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);
}
})
);
如有任何帮助,我们将不胜感激!
我创建了一个 stackblitz 来重现这个问题:
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;
方法一:
使用setTimeout
达到想要的效果,使用如下-
setTimeout(()=>{
this.optionForm.patchValue({selectedOption: 'test'});
}, 0);
方法二:
这种方法在没有 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'});
我正在尝试重新填充使用 mat-autocomplete 的输入。但是,每当我发送带有 this.optionForm.patchValue({selectedOption: 'my value'})
的值时,结果都不会显示在 GUI 中。如果我 console.log()
我可以清楚地看到设置的值。我不确定这个问题是否与我有时将一个对象设置到字段中而其他时候只设置一个字符串这一事实有关?但我希望能够用结果重新填充输入并适当地显示它。无论我如何尝试,我似乎都无法显示结果。
下面是我的组件,仅包含有问题的输入和正在为 mat-autocomplete
获取结果的 Observable。这些在第一次使用表单时工作正常。
// 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);
}
})
);
如有任何帮助,我们将不胜感激!
我创建了一个 stackblitz 来重现这个问题:
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;
方法一:
使用setTimeout
达到想要的效果,使用如下-
setTimeout(()=>{
this.optionForm.patchValue({selectedOption: 'test'});
}, 0);
方法二:
这种方法在没有 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'});