Как работает этот угловой канал, используемый для динамического поиска терминов, вставленных во входной тег, на мой взгляд? - PullRequest
0 голосов
/ 08 ноября 2018

Я очень новичок в Angualar, и я следую этому официальному учебнику по Angular: https://angular.io/tutorial/toh-pt6

и у меня есть некоторые сомнения относительно того, как это работает, это мой закомментированный код класса HeroSearchComponent :

import { Component, OnInit } from '@angular/core';

import { Observable, Subject } from 'rxjs';

import {
   debounceTime, distinctUntilChanged, switchMap
 } from 'rxjs/operators';

import { Hero } from '../hero';
import { HeroService } from '../hero.service';

@Component({
  selector: 'app-hero-search',
  templateUrl: './hero-search.component.html',
  styleUrls: [ './hero-search.component.css' ]
})
export class HeroSearchComponent implements OnInit {

  // It is an Observable emitting an array of Hero objects:
  heroes$: Observable<Hero[]>;

  /**
   * The searchTerms property is declared as an RxJS Subject.
   * A Subject is both a source of observable values and an Observable itself. 
   * You can subscribe to a Subject as you would any Observable.
   * You can also push values into that Observable by calling its next(value) method as the search() method does.
   */
  private searchTerms = new Subject<string>();

  constructor(private heroService: HeroService) {}

  /**
   * Push a search term into the observable stream.
   * Every time the user types in the textbox, the binding calls search() with the textbox value, a "search term". 
   * The searchTerms becomes an Observable emitting a steady stream of search terms. 
   */ 
  search(term: string): void {
    this.searchTerms.next(term);
  }

  ngOnInit(): void {
    this.heroes$ = this.searchTerms.pipe(
      // wait 300ms after each keystroke before considering the term
      debounceTime(300),

      // ignore new term if same as previous term
      distinctUntilChanged(),

      // switch to new search observable each time the term changes
      switchMap((term: string) => this.heroService.searchHeroes(term)),
    );
  }
}

Этот класс используется для поиска героев из hero-search.component.html , содержащего:

<div id="search-component">
  <h4>Hero Search</h4>

  <!--
    As the user types in the search box, a keyup event binding calls 
    the component's search() method with the new search box value
  -->
  <input #searchBox id="search-box" (keyup)="search(searchBox.value)" />

  <ul class="search-result">
    <!--
        The *ngFor iterates over a list called heroes$, not heroes.
        The $ is a convention that indicates heroes$ is an Observable, not an array.
        The *ngFor can't do anything with an Observable. 
        But there's also a pipe character (|) followed by async, which identifies Angular's AsyncPipe.
        The AsyncPipe subscribes to an Observable automatically so you 
        won't have to do so in the component class.
    -->
    <li *ngFor="let hero of heroes$ | async" >
      <a routerLink="/detail/{{hero.id}}">
        {{hero.name}}
      </a>
    </li>
  </ul>
</div>

Вот мое толкование, я абсолютно не уверен, правильно это или нет.

Поле heroes $ HeroSearchComponent не является массивом, но Observable испускает массив. Это потому, что мы живем в асинхронном мире, поэтому нам приходится ждать ответа от сервера.

В представлении я не могу напрямую выполнять итерации для массива, но мне приходится ждать, пока я получу ответ (когда предыдущая наблюдаемая испускает массив Hero ), это делается с помощью асинхронный канал для регистрации на это событие:

<li *ngFor="let hero of heroes$ | async" >

Это должно быть правильно ...

Тогда в представлении у меня есть:

<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />

Когда пользователь вставляет новый символ во входной тег, он называется компонентом search () метод, передающий значение, вставленное во входной тег («a», «ab», «abc», "ab" и т. д.).

Это метод поиска () :

search(term: string): void {
  this.searchTerms.next(term);
}

Глядя на это, вы напрямую не выполняете поиск, вызывающий внутреннюю службу, но толкаете полученный новый термин в searchTerms .

Этот searchTerms объект является Subject . Из того, что я понял, Субъект является объектом, который может генерировать событие (как наблюдаемое **) и в то же время может принимать поток четных чисел (в данном случае поток терминов каждый раз, когда пользователь вставляет новый символ в вид поиска ввода).

Но ... как и где выполняется вызов для получения списка героев, совпадающего с введенным термином?

Моя идея заключается в следующем: это напрямую не делается в этом методе, но есть что-то вроде предустановленного поведения. Это делается, когда этот класс создается методом ngOnInit () :

ngOnInit(): void {
  this.heroes$ = this.searchTerms.pipe(
    // wait 300ms after each keystroke before considering the term
    debounceTime(300),

    // ignore new term if same as previous term
    distinctUntilChanged(),

    // switch to new search observable each time the term changes
    switchMap((term: string) => this.heroService.searchHeroes(term)),
  );
}

Это в основном говорит что-то вроде: вызовите метод heroService.searchHeroes (term) (метод, выполняющий поиск в моем бэкэнде), передавая term каждый раз, когда searchTerms получать \ отправлять событие (это последний термин для поиска). Теоретически этот канал настроен так, чтобы делать это не для каждого вставленного символа, а каждые 300 мс, чтобы избежать большого количества вызовов).

Я не уверен насчет этого механизма и того, как именно работает эта труба.

Что такое правильная и полная интерпретация?

1 Ответ

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

Что такое функция pipe () в Angular 2?

У нас есть концепция труб в Angular и функция pipe () в RxJS

1) Трубы в угловом формате: труба принимает данные в качестве входных данных и преобразует их в желаемый выходной https://angular.io/guide/pipes

2) Функция pipe () в RxJS: Вы можете использовать каналы для связи операторов. Трубы позволяют объединить несколько функций в одну функцию.

Функция pipe () принимает в качестве аргументов функции, которые вы хотите объединить, и возвращает новую функцию, которая при выполнении запускает составные функции в последовательности. https://angular.io/guide/rx-library (поиск труб в этом URL, вы можете найти то же самое)

...