Angular Reactive Form patchValue () не заполняет ввод, связанный с mat-autocomplete

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

Any help would be appreciated!


person SortingHat    schedule 11.02.2019    source источник
comment
stackblitz упростит нам помощь в этом   -  person Akber Iqbal    schedule 12.02.2019
comment
попробуйте это this.resultOptions = [...this.resultOptions], после обновления resultOptions,   -  person Abhishek Kumar    schedule 12.02.2019
comment
@AbhishekKumar - это Observable, поэтому Typescript жалуется на: Type 'any[]' is not assignable to type 'Observable<any[]>'.   Property '_isScalar' is missing in type 'any[]'.   -  person SortingHat    schedule 13.02.2019
comment
@AkberIqbal хорошая идея! Я добавлю стекблиц!   -  person SortingHat    schedule 13.02.2019


Ответы (2)


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

Демо без async оператор

person Abhishek Kumar    schedule 13.02.2019
comment
Спасибо за предложенное решение; однако проблема не в этом. Проблема, описанная в другом моем ответе, заключается в том, что функция отображения возвращает значение null для несуществующего свойства. - person SortingHat; 21.02.2019
comment
@daswolle из вопроса и stackblitz предполагалось, что параметры не отображались в поле выбора после обновления наблюдаемого массива, поэтому я ответил на вопрос соответствующим образом. Но ничего страшного, если вопрос решен. - person Abhishek Kumar; 21.02.2019
comment
Да, спасибо @abhishek, я ценю ваш вклад. Вопросы и отзывы помогли все прояснить! - person SortingHat; 04.03.2019

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

https://stackblitz.com/edit/material-6-gh3rmt?file=app/app.component.ts

Поступая так, я понимаю, в чем была проблема! Имея функцию отображения, возвращающую какое-то свойство объекта, она, очевидно, отображает пустую строку. Итак, объект устанавливается, и его можно увидеть в форме, но, поскольку я использовал настраиваемую функцию отображения, он запускается нулевым свойством в строке.

Надеюсь, я смогу помочь другим людям, которые могут столкнуться с этой проблемой в будущем!

Чтобы конкретизировать это решение:

  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;
person SortingHat    schedule 12.02.2019
comment
Отлично ... Мы все можем узнать, что воссоздание минимального, поддающегося проверке примера часто заставляет всплыть на поверхность, что упрощает решение :) - person Akber Iqbal; 13.02.2019
comment
@daswolle, спасибо за предоставление stackblitz, но он должен быть в обновленном вопросе и не должен публиковаться в качестве ответа, поскольку это не решение, а расширение вопроса. Спасибо. И пожалуйста, посмотрите мой ответ и прокомментируйте проблемы, чтобы мы могли устранить проблемы и исправить решение. - person Abhishek Kumar; 13.02.2019
comment
@AbhishekKumar, вы правы, stackblitz в настоящее время не представляет решения. Я обновлю этот пост, чтобы более конкретно рассмотреть проблему в том виде, в котором она представлена. - person SortingHat; 21.02.2019
comment
@daswolle спасибо, что сделали это ответом на вопрос, это будет полезно для других. - person Abhishek Kumar; 21.02.2019