ngFor在ngIf中使用异步管道进行观测

时间:2019-08-27 08:23:11

标签: angular rxjs

我输入的下拉列表没有显示结果。它在带有异步的ngIf中。当我删除ngIf代码时,将显示下拉列表,因此我认为它必须是ngIf检查或如何设置测试可观察服务。当我按下输入1值的键时,什么都没有显示,第二次输入键时,它显示了列表。

<div class="format-options" *ngIf="(definitions | async)?.length > 0">
  <div *ngFor="let definition of definitions | async" class="search-result">
    <div>{{definition.name}}</div>
    <div>{{definition.description}}</div>
  </div>
</div>

搜索服务:

searchTerm(term: string): Observable<Array<ObjectDefinition>>

    let observer = new Observable<Array<ObjectDefinition>>((subscription) => {

      const timer$ = interval(1000);

      timer$.subscribe(() => {
        console.log('timer 1 second');
        subscription.next(this.objectDefinitions);
        subscription.complete();
      });

    });

    return observer;
}

组件:

constructor(private definitionService: DefinitionService) {
    this.definitions = this.searchInput.valueChanges
                        .pipe(
                            tap(value => console.log('input')),
                            //startWith(''),
                            debounceTime(500),
                            //distinctUntilChanged(),
                            switchMap(value => this.definitionService.searchTerm(value))
                        );
  }

2 个答案:

答案 0 :(得分:2)

我猜第一个*ngIf通过async管道进行订阅。返回结果后,可观察对象将完成,*ngFor将尝试使用已完成但不可回放的可观察对象,而不重播它的最后一次发射。您可以通过添加shareReplay(1)管道来解决此问题:

this.definitions = this.searchInput.valueChanges.pipe(
  tap(value => console.log('input')),
  debounceTime(500),
  switchMap(value => this.definitionService.searchTerm(value)),
  shareReplay(1)
);

整个searchTerm的可观察性看起来有些怪异,您应该看看如何改进它,但是要在此实现要有点困难。您是否要以1000ms的时间对其进行反跳并仅发射一次?

为防止在模板中使用双重订阅,您还可以对模板进行一些更改:

<ng-container *ngIf="definitions | async as defs">
  <div class="format-options" *ngIf="defs.length > 0">
    <div *ngFor="let definition of defs" class="search-result">
      <div>{{definition.name}}</div>
      <div>{{definition.description}}</div>
    </div>
  </div>
</ng-container>

答案 1 :(得分:2)

您可以像这样直接在* ngIf指令中设置异步操作的结果:

<div class="format-options" *ngIf="definitions | async as defs">
  <div *ngFor="let definition of defs" class="search-result">
    <div>{{definition.name}}</div>
    <div>{{definition.description}}</div>
  </div>
</div>

然后不需要第二个异步管道。

PS:切勿使用RxJs运算符订阅您的服务。