Как заставить поле ввода `searchTerm` наблюдать за изменением его значения? - PullRequest
0 голосов
/ 21 октября 2018

У меня есть две наблюдаемые, которые отлично работают:

@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;

ngOnInit() {
  ...
  merge(this.sort.sortChange, this.paginator.page)
  .pipe(
    startWith({}),
    switchMap(() => {
      return this.getUsers(this.sort.active, this.sort.direction, this.paginator.pageIndex);
    }),
    map(userApi => {

Это позволяет вызывать сервисный метод getUsers при обновлении сортировки или нумерации страниц.

Теперь яХотелось бы также, чтобы этот метод обслуживания вызывался при вводе условия поиска:

@ViewChild(String) searchTerm: string;
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;

ngOnInit() {
  ...
  merge(this.searchTerm.length, this.sort.sortChange, this.paginator.page)
  .pipe(
    startWith({}),
    switchMap(() => {
      return this.getUsers(this.searchTerm, this.sort.active, this.sort.direction, this.paginator.pageIndex);
    }),
    map(userApi => {

со следующей разметкой шаблона:

<mat-form-field>
    <input matInput #searchTerm (keyup)="search($event.target.value)" placeholder="User name" autocomplete="off">
</mat-form-field>

Но метод обслуживания тогда никогда не будетвызывается, даже во время загрузки страницы.

Моя идея состоит в том, чтобы searchTerm был наблюдаемым, и чтобы эта наблюдаемая наблюдалась методом merge.Таким образом, у меня есть только один вызов метода getUsers.

Я также попробовал этот оператор (без .length), но он ничего не изменил:

merge(this.searchTerm, this.sort.sortChange, this.paginator.page)

ОБНОВЛЕНИЕ: я сейчас пытаюсь что-то в этом духе:

@ViewChild('searchTerm') searchTerm: ElementRef;

merge(this.searchTerm.nativeElement.changes, this.sort.sortChange, this.paginator.page)

Обработчик событий search прекрасно обновляет переменную-член searchTerm:

  search(searchTerm: string) {
    this.searchTerm.nativeElement.value = searchTerm.trim().toLowerCase();

    if (this.paginator) {
      this.paginator.firstPage();
    }
  }

Я полагаю, что могуполучить значение элемента поля ввода для вызова метода службы:

return this.getUsers(this.searchTerm.nativeElement.value, this.sort.active, this.sort.direction, this.paginator.pageIndex);

Но merge не срабатывает, если оно включает this.searchTerm.nativeElement.changes, как в:

merge(this.searchTerm.nativeElement.changes, this.sort.sortChange, this.paginator.page)

Как можно наблюдать поле ввода searchTerm для изменения его значения?

1 Ответ

0 голосов
/ 22 октября 2018

Наконец-то я смог решить проблему, используя объект EventEmitter:

@Input() searchTerm: string;
@Output() searchTermEvent = new EventEmitter<{ value: string }>();

merge(this.searchTermEvent, this.sort.sortChange, this.paginator.page)
  .pipe(
    startWith({}),
    switchMap(() => {
      this.isLoadingResults = true;
      return this.getUsers(this.searchTerm, this.sort.active, this.sort.direction, this.paginator.pageIndex);
    }),

Событие отправляется обработчиком:

search(searchTerm: string) {
  this.searchTerm = searchTerm;
  this.searchTermEvent.emit({
    value: this.searchTerm
  });

  if (this.paginator) {
    this.paginator.firstPage();
  }
}

Сервисный метод getUsersсрабатывает при каждом вводимом символе.

Может быть, есть лучшая альтернатива, но пока это работает отлично.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...