【问题标题】:How to show loading template using OnPush change detection?如何使用 OnPush 更改检测显示加载模板?
【发布时间】:2021-11-10 22:54:01
【问题描述】:

所以我正在听一个路由参数:

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,并希望继续这样做

这在组件第一次初始化时非常有用。

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

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

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

是否有一种 OnPush 友好的方式来让加载模板显示路由 paramMap observable 何时提供新值?

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

StackBlitz Here

【问题讨论】:

    标签: angular rxjs angular-router async-pipe


    【解决方案1】:

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

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

    【讨论】:

    • 做得很好。很好,谢谢。我觉得我不知道存在的 rxjs 运算符列表几乎是无底的。 :)
    • 哈哈,是的,很多运营商...!
    • 这仍然是正确的答案,但由于 startWith(undefined) 导致 IDE 对我咆哮,我将在此处链接到该问题的答案:stackoverflow.com/questions/56571406/…
    猜你喜欢
    • 2020-10-04
    • 2019-09-18
    • 2021-03-06
    • 2021-08-04
    • 2017-09-28
    • 2018-10-15
    • 1970-01-01
    • 1970-01-01
    • 2020-02-07
    相关资源
    最近更新 更多