Угловая реактивная форма patchValue () не заполняет ввод, связанный с mat-autocomplete - PullRequest
0 голосов
/ 12 февраля 2019

Я пытаюсь повторно заполнить ввод, который использует автозаполнение матов.Однако всякий раз, когда я отправляю значение с 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 ]

0 голосов
/ 13 февраля 2019

Подход 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'}); 

Демонстрация без асинхронного оператора

0 голосов
/ 13 февраля 2019

Я создал стек, чтобы воспроизвести проблему:

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;
...