Emptyform
@Emptyform

[Angular] Выбор данных для выпадающего списка (typeahead) — правильно ли сделано?

Задача: написать выпадающий список - по мере ввода в <input> показывать выпадающий список, где данные отфильтрованы согласно введенной строке.

Выбор данных сделал так:
Observable.fromEvent(this.myInput.nativeElement, 'input')
  .map(e => e.target.value)
  .subscribe(searchText => {
    this.http.get(URL_API)
      .map(res => res.json())
      .subscribe(users => {
        this.userNames =
          users.map(item => item.fullName)
               .filter(item => item.toLowerCase().includes(searchText.toLowerCase()))
      })
  });

Код упрощен для наглядности (убрал указание типов, паузу после окончания ввода, проверку длины введенной строки и пр.)

Нормальный это вариант или можно лучше?
Меня, в общем-то смущает subscribe внутри другого subscribe
  • Вопрос задан
  • 1334 просмотра
Решения вопроса 1
@Makito
Ну во-первых у вас как то странно работает сам поиск, получается что вы каждый раз загружаете всех пользователей и потом по этой выборке локально ищите вхождения.
Вам нужно либо один раз при инициализации загрузить весь список пользователей и положить его к примеру в _source а потом при вводе текста фильтровать этот список и не мучить сервер запросами, либо если пользователей много то на сервере должен быть реализован метод для поиска сотрудников по строке.
Во-вторых, да, код написан не совсем верно.
Если вы хотите чтобы сервер искал и возвращал только подходящее то:
Observable.fromEvent(this.myInput.nativeElement, 'input')
    .debounceTime(500)
    .map(e => e.target.value)
    .switchMap(searchText => this.http.get(`URL_API&q=${searchText}`))
    .map(res => res.json())
    .subscribe(users => this.userNames = users);


Если же вы хотите искать по локально сохранённой коллекции пользователей то:
Observable.fromEvent(this.myInput.nativeElement, 'input')
    .debounceTime(500)
    .do(e => this.searchText = e.target.value)
    .switchMap(() => Observable.from(this._source))
    .subscribe(users => this.userNames = users.map(item => item.fullName)
               .filter(item => item.toLowerCase().includes(searchText.toLowerCase())));

Мой код может быть не на все сто рабочим но общий посыл должен быть таким.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы