角反应形式patchValue()不会填充连接到mat-autocomplete的输入

时间:2019-02-11 23:48:48

标签: angular angular-material observable angular-reactive-forms mat-autocomplete

我正在尝试重新填充使用mat-autocomplete的输入。但是,每当我使用this.optionForm.patchValue({selectedOption: 'my value'})发送值时,结果都不会显示在GUI中。如果我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 个答案:

答案 0 :(得分:0)

我创建了一个堆栈闪电来重现该问题:

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 :(得分:0)

方法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'}); 

Demo without async operator