如何使用 OnPush 变化检测显示加载模板?

How to show loading template using OnPush change detection?

所以我正在监听路由参数:

searchResults$: Observable<string[]>;

constructor(
  private route: ActivatedRoute,
  private svc: SearchService) { 
  this.searchResults$ = this.route.paramMap.pipe(
    map((p: ParamMap) => p.get('searchTerm')),
    switchMap((searchTerm: string) => this.svc.getSearchResults(searchTerm))
  );
}

...我正在用异步管道解包...

<p>Search Results</p>

<ul *ngIf="searchResults$ | async as results; else loading">  
    <li *ngFor="let r of results">
        {{ r }}
    </li>
</ul>

<ng-template #loading>Loading!!11!</ng-template>

我正在使用 ChangeDetectionStrategy.OnPush,并希望继续使用

每当组件首次初始化时,这都非常有效。

但是,如果我使用 angular 路由器提供不同的路由参数(组件仍在加载时):

this.router.navigate(['search/${searchTerm}`])

那么 searchResult$ observable 永远不会未定义并且 else loading 永远不会被调用。新列表仅替换旧列表,而不向用户指示正在加载。

是否有一种 OnPush 友好的方式来让加载模板在路由 paramMap 可观察对象提供新值时显示?

我试过返回默认更改检测并将一堆 tap(() => this.isloading = true;) 扔到我的可观察组合中 - 但我不想这样做,我想看看我是否可以做这是在使用 OnPush 变化检测时。

StackBlitz Here

你可以简单地让你的 switchMapped observable startWith undefined:

  this.searchResults$ = this.route.paramMap.pipe(
    map(p => p.get('searchTerm')),
    switchMap(searchTerm => this.svc.getSearchResults(searchTerm).pipe(
      startWith(undefined)
    ))
  );