Привязка Angular Material к событию отменяет подписку valueChanges - PullRequest
0 голосов
/ 27 декабря 2018

У меня довольно простое автозаполнение с Angular Material (6).Вот базовая реализация:

<mat-form-field>
    <input type="text" matInput placeholder="Company" formControlName="company" [matAutocomplete]="autoCo"/>
    <mat-autocomplete #autoCo="matAutocomplete" [displayWith]="displayCo">
        <mat-option *ngFor="let company of filteredCompanies | async" [value]="company">
            {{ company.companyName }}
        </mat-option>
    </mat-autocomplete>
</mat-form-field>

Это работает без проблем.Тем не менее, я хочу, чтобы что-то произошло, когда выбор сделан.Для этого я добавил (optionSelected)="onSelectionChanged($event)" к элементу mat-autocomplete.Изначально все работает как положено (работает фильтрация опций).После выбора функция onSelectionChanged также срабатывает, как и ожидалось.

Однако после выбора выбранный элемент является единственным элементом, доступным в раскрывающемся меню автозаполнения, независимо от того, какие изменения внесены.Я делаю.Поэтому, даже если я удалю весь текст на входе, я все равно вижу только ранее выбранную опцию.Вместо этого я ожидаю увидеть полный список.

В ngOnInit у меня есть:

this.filteredCompanies = this.companyForm.get("company").valueChanges.pipe(
        debounceTime(200))
        .pipe(mergeMap(val => this.filter(val)));

Похоже, что подписка valueChanges завершится, если я свяжусь с optionSelected.Если я не привязываюсь к optionSelected, список параметров обновляется, как и ожидалось.

Неправильно ли я привязан к событию optionSelected?Нужно ли повторно подписываться на форму valueChanges из onSelectionChanged() ??Если да, то почему?

Для чего это стоит, вот еще какой-то соответствующий код:

@Output()
optionSelected = new EventEmitter();

onSelectionChanged(event: any) {
    console.log(event);
    this.optionSelected.emit(event);
}

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Чтобы попытаться ответить на ваш вопрос, я сначала попытался воспроизвести проблему.Я создал следующее:

StackBlitz .

Я должен был сделать ряд предположений для кода, который вы не включили, но для кода, который вы включили, я существенно его не изменил (за исключением добавления иногда console.log).

Как вы можете видеть в StackBlitz, описанная вами проблема не возникает.

Это может быть связано с кодом, которым вы не поделились.Пожалуйста, сравните StackBlitz с вашим кодом.Если есть разница, пожалуйста, поделитесь другим кодом, и я обновлю StackBlitz для повторного тестирования.

Некоторые примечания:

  • Я только что использовал «hello-component» по умолчаниюдля вашего кода.
  • Я создал простой метод filter (), поскольку вы не предоставили код для этого.
  • Я создал простой метод displayCo (), поскольку вы не предоставили этот код.
  • Я предполагал, что родительский компонент предоставил список опций этому дочернему компоненту через вход, называемый companies, который является Company[].
  • Я также сделал ряд предположений относительнокак вы создали свою форму, поскольку она также не была включена в ваш вопрос.

Надеюсь, это поможет найти основную причину вашей проблемы.

Обновление

Ваш код из отредактированного StackBlitz, который вы указали в комментариях ниже, вызывает:

this.companyForm.setControl("company", this.setCompany(newSelection));

Но this.setCompany возвращает FormGroup, а .setControl() требуется FormControl в качестве второго параметра.Вы должны иметь возможность просто обновить существующую группу FormGroup примерно так:

this.companyForm.get('company').setValue(newSelection);

Обновлен StackBlitz здесь .

0 голосов
/ 27 декабря 2018

Вы действительно подписываетесь на valueChanges?Из вашего кода это не похоже на это.Я думаю, что вы пропускаете .subscribe() вызов.

this.filteredCompanies = this.companyForm.get("company").valueChanges
  .pipe(debounceTime(200))
  .pipe(mergeMap(val => this.filter(val)))
  .subscribe(() => {});

Также ваша привязка к onSelectionChanged несколько неверна, это:

@Output()
optionSelected = new EventEmitter();

onSelectionChanged(event: any) {
  console.log(event);
  this.optionSelected.emit(event);
}

можно упростить до:

onSelectionChanged(event: any) {
  console.log(event);
  // do what you want here
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...