Автозаполнение с Angular и RXJS - PullRequest
1 голос
/ 04 июня 2019

Новичок в RXJS и пытается выяснить, как настроить автозаполнение. Прямо сейчас у меня есть компонент typeahead, который обрабатывает элемент input и выдает значение ('term'). В моем filters компоненте (родительском) я управляю логикой совершения вызовов API и работы с данными (через службу). У меня есть функция в этом компоненте, которая вызывается с изменением term и выполняет вызов API. Возникли проблемы с настройкой этого с некоторыми примерами, которые я видел, а именно, SwitchMap, кажется, необходим для правильных вызовов. В основном функция должна делать 2 вещи: 1. Отправлять запросы в API и обрабатывать возвращаемые данные. 2. Вставьте его в список, который будет отображаться в качестве параметров автозаполнения. Прямо сейчас это выглядит так, но есть синтаксическая ошибка:

public IdTypeahead(term: string) {
    this.model.NctIdList = [];

    if (!(term && term.length > 0)) {
      return;
    }

    this.searchCriteria.nctIdPrefix = term;
    this.searchCriteria.aggregateOn = 'nctid';
    // this.NctIdList = of(term)
    let input$ = of(term)
      .switchMap(() => from(this.filterService.GetNctIdFilterData(this.searchCriteria))
          .subscribe((result: any) => {
            this.NctIdList.push(result.nctid)
              return result.nctid
          }

          )
  }

Раньше это выглядело так, но делали неправильные звонки (звонки запаздывали):

public IdTypeahead(term: string) {
    this.model.NctIdList = [];

    if (!(term && term.length > 0)) {
      return;
    }

    this.searchCriteria.nctIdPrefix = term;
    this.searchCriteria.aggregateOn = 'nctid';
    this.NctIdList = 
    this.filterService.GetNctIdFilterData(this.searchCriteria).pipe(
    map((result: any) => result.nctid) as Observable<string[]>
  }

Ответы [ 2 ]

1 голос
/ 04 июня 2019

Я бы предложил первую тему настройки, которая отвечает за изменение сроков и в зависимости от того, что вы выполняете.Как я понимаю ваш вариант использования, я бы предложил:

  import { Subject } from 'rxjs';
  import { takeUntil, switchMap, filter, tap } from 'rxjs/operators';

  private term$ = new Subject<string>();

  // execute setup only once, for example in ngOnInit()
  private setup() {
    this.term$
      .pipe(
        filter((term) => term && term.length > 0),
        tap((term) => {
          this.model.NctIdList = [];
          this.searchCriteria.nctIdPrefix = term;
          this.searchCriteria.aggregateOn = 'nctid';
        }),
        switchMap((_) =>
          this.filterService.GetNctIdFilterData(this.searchCriteria),
        ),
      )
      .subscribe((result: any) => {
        this.NctIdList.push(result.nctid);
      });
  }

  public IdTypeahead(term: string) {
    this.term$.next(term);
  }
1 голос
/ 04 июня 2019

Это то, что вы должны сделать -

export class YourComponent implements OnInit {

  listToShowInAutoComplete$: Observable<string>;
  serachTerm$: BehaviorSubject<string> = new BehaviorSubject<string>(null);

  constructor() { }

  ngOnInit() {

    this.listToShowInAutoComplete$ = this.serachTerm$.pipe(
                                        debounceTime(200),
                                        distinctUntilChanged(),
                                        filter(t => !!t),
                                        switchMap(term => {
                                          this.searchCriteria.nctIdPrefix = term;
                                          this.searchCriteria.aggregateOn = 'nctid';
                                          return this.filterService.GetNctIdFilterData(this.searchCriteria);
                                        }),
                                        map(result => {
                                          //i am assuming that result is your list which is to be shown in the autocomplete options
                                          //adjust this code as per your api response
                                          //idea here is to project the result to the items to be shown in autocomplete
                                          return result;
                                        })
                                    );
  }

  IdTypeahead(term: string) {
    this.serachTerm$.next(term);
  }

}

теперь вы должны связать listToShowInAutoComplete $ в вашем шаблоне следующим образом -

<your-auto-complete-comp [yourPropery]="listToShowInAutoComplete$ | async"></your-auto-complete-comp>

Импорт необходимых конструкций по мере необходимости. Надеюсь, что это даст вам представление о том, как реализовать typeahead. Настройте логику фильтра в соответствии с потребностями вашего бизнеса.

...