繁体   English   中英

带输入的角度异步管道

[英]Angular async pipe with input

我正在从 json 获取一个列表,我想显示该列表并能够使用输入框进行过滤。 到目前为止它正在工作,但列表仅在我在搜索框中输入内容后才会显示。 我想在开始时显示列表。我试图在开始时用空字符串设置搜索框值,但它不起作用。 查了网上也没找到实现的方法。 任何帮助,将不胜感激。

我的组件html:


<h4><label for="search-box">Hero Search</label></h4>

<input #searchBox id="search-box" (input)=search(searchBox.value)  />
<ul class="heroes">
  <li *ngFor="let hero of heroes$ | async">
    <a routerLink="/detail/{{hero.id}}">
      <span class="badge">{{hero.id}}</span> {{hero.name}}
    </a>
    <button class="delete" title="delete hero"
  (click)="delete(hero)">Delete</button>
  </li>
</ul>
<div>
  <label>Hero name:
    <input #heroName />
  </label>
  <!-- (click) passes input value to add() and then clears the input -->
  <button (click)="add(heroName.value); heroName.value=''">
    add
  </button>
</div>

组件 ts:

  selector: 'app-heroes',
  templateUrl: './heroes.component.html',
  styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {
  heroes$: Observable<Hero[]>=null;
  heroes: Hero[];
  selectedHero: Hero;
  private searchTerms = new Subject<string>();
  constructor(private heroService: HeroService) {
  }

  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)),
      );


    }

  // Push a search term into the observable stream.
  search(term: string): void {
    this.searchTerms.next(term);

  }

  getHeroes(): void {
    this.heroService.getHeroes()
      .subscribe(heroes => this.heroes = heroes);

  }

服务:

/* GET heroes whose name contains search term */
  searchHeroes(term: string): Observable<Hero[]> {
    if (!term.trim()) {
      // if not search term, return full array.
      return this.getHeroes();
    }
    return this.http.get<Hero[]>(`${this.heroesUrl}/?name=${term}`).pipe(
      tap(x => x.length ?
        this.log(`found heroes matching "${term}"`) :
        this.log(`no heroes matching "${term}"`)),
      catchError(this.handleError<Hero[]>('searchHeroes', []))
    );
  }

您可以将 searchTerm 声明为 BehaviorSubject 而不是简单的 Subject。 主要区别在于,作为该 BehaviorSubject 的订阅者,无论您的订阅何时发生,您都将获得该 observable 发出的最后一个值。 请注意 BehaviorSubject 需要一个初始值,该值将在您初始化时发出。

private searchTerms: BehaviorSubject<string> = new BehaviorSubject<string>('');

因为在您的情况下它连接到输入事件,所以您需要自动触发第一个值来启动您的管道。 您可以使用startWith运算符来执行此操作

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

    startWith(''), // <-- start your pipe with an empty string

    // 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)),
  );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM