Angular 角度反应形式patchValue()不';t填充输入连接到mat自动完成

Angular 角度反应形式patchValue()不';t填充输入连接到mat自动完成,angular,angular-material,observable,angular-reactive-forms,mat-autocomplete,Angular,Angular Material,Observable,Angular Reactive Forms,Mat Autocomplete,我正在尝试重新填充使用mat自动完成的输入。但是,每当我使用this.optionForm.patchValue({selectedOption:'my value'})发送值时,结果不会显示在GUI中。如果我console.log()我可以清楚地看到该值已设置。我不确定这个问题是否与我有时在字段中设置一个对象,而有时只设置一个字符串有关?但是我希望能够用结果重新填充输入并适当地显示它。无论我如何尝试,我似乎都无法显示结果 下面是我的组件,只包含有问题的输入和我的可观察到的内容,这些内容正在为m

我正在尝试重新填充使用mat自动完成的输入。但是,每当我使用
this.optionForm.patchValue({selectedOption:'my value'})发送值时,
结果不会显示在GUI中。如果我
console.log()
我可以清楚地看到该值已设置。我不确定这个问题是否与我有时在字段中设置一个对象,而有时只设置一个字符串有关?但是我希望能够用结果重新填充输入并适当地显示它。无论我如何尝试,我似乎都无法显示结果

下面是我的组件,只包含有问题的输入和我的可观察到的内容,这些内容正在为
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>

任何帮助都将不胜感激

我创建了一个stackblitz来重现这个问题:

在这样做的过程中,我意识到了问题所在!通过让display函数返回对象的某些属性,它显然会为字符串显示空。因此,对象正在被设置,并且可以在表单中看到,但是因为我使用了一个自定义显示函数,它被字符串上的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;

我创建了一个stackblitz来重现这个问题:

在这样做的过程中,我意识到了问题所在!通过让display函数返回对象的某些属性,它显然会为字符串显示空。因此,对象正在被设置,并且可以在表单中看到,但是因为我使用了一个自定义显示函数,它被字符串上的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'}); 

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


stackblitz将使我们更容易帮助您尝试此
this.resultOptions=[…this.resultOptions]
,在更新
resultOptions
后,@AbhishekKumar是可观察的,因此Typescript抱怨:
Type'any[]不可分配给Type'observatable'。类型“any[]”中缺少属性“u isScalar”。
@AkberIqbal好主意!我要加一个闪电战!stackblitz将使我们更容易帮助您尝试此
this.resultOptions=[…this.resultOptions]
,在更新
resultOptions
后,@AbhishekKumar是可观察的,因此Typescript抱怨:
类型“any[]”不可分配给类型“observatable”。类型“any[]”中缺少属性“u isScalar”。
@AkberIqbal好主意!我要加一个闪电战!杰出的我们都可以了解到,重新创建一个最小的、可验证的示例通常会使核心问题浮出水面,从而更容易解决:)@daswolle,感谢提供stackblitz,但它应该在更新的问题中,不应该作为答案发布,因为它不是解决方案,而是问题的扩展。非常感谢。请查看我的答案,并对问题进行评论,这样我们就可以删除问题以修复解决方案。@AbhishekKumar你说得对stackblitz目前并不代表解决方案。我将更新这篇文章,以便更具体地解决所提出的问题。@daswolle感谢您回答这个问题,这将对其他人有所帮助。非常好。。。我们都可以了解到,重新创建一个最小的、可验证的示例通常会使核心问题浮出水面,从而更容易解决:)@daswolle,感谢提供stackblitz,但它应该在更新的问题中,不应该作为答案发布,因为它不是解决方案,而是问题的扩展。非常感谢。请查看我的答案,并对问题进行评论,这样我们就可以删除问题以修复解决方案。@AbhishekKumar你说得对stackblitz目前并不代表解决方案。我将更新这篇文章,以便更具体地解决所提出的问题。@daswolle感谢您对这个问题的回答,这将对其他人有所帮助。感谢您提出的解决方案;然而,这不是问题所在。在我的另一个回答中所描述的问题是,display函数为不存在的属性返回null。@daswolle从问题中得出,stackblitz假设选项在更新可观察数组后没有显示在选择框中,因此我相应地回答了问题。但如果问题已经解决,那就好了。是的,谢谢你@abhishek,我感谢你的意见。这些问题和反馈有助于澄清一切!感谢您提出的解决方案;然而,这不是问题所在。在我的另一个回答中所描述的问题是,display函数为不存在的属性返回null。@daswolle从问题中得出,stackblitz假设选项在更新可观察数组后没有显示在选择框中,因此我相应地回答了问题。但如果问题已经解决,那就好了。是的,谢谢你@abhishek,我感谢你的意见。这些问题和反馈有助于澄清一切!