Angular ngIf 与 Async Pipe

情境

当我们在 template 订阅一组资料,而需要对它做一些逻辑处理的时後。

不好的方式

.ts

export class TemplateComponent {
  products$: Observable<any> = this.apiService.fetchProd();
  constructor(public apiService: ApiService) {}
}

.html

<ng-container *ngIf="products$ | async as products;">
  <ng-container *ngIf="products.length > 0; else empty">
    <ng-container *ngFor="let item of products"> ...略 </ng-container>
  </ng-container>
</ng-container>
<ng-template #empty> No Data </ng-template>

若像上述这样的写法,会造成重覆订阅而增加 server 的负担,所以在实作上,通常会避免这情况发生


解决方式

使用 ngIf as

将 html 写法稍做修改

<ng-container *ngIf="(products$ | async)?.length > 0 as products; else empty">
  <ng-container *ngFor="let item of products"> ...略 </ng-container>
</ng-container>
<ng-template #empty> No Data </ng-template>

products$ | async 定义为 products
这样就只会被订阅一次,而这麽做的好处也可以使程序码更容易阅读,


加上 shareReplay

在 ts 档里加上 shareReplay
.ts

export class TemplateComponent {
  products$: Observable<any> = this.apiService.fetchProd().pipe(
      shareReplay()
  );
  constructor(public apiService: ApiService) {}
}

还有一点要注意的是,在 ng-container 里,不能同时使用 ngIfngFor 否则会报错唷唷唷~

明天会接续来说 ng-container 与 ng-template 这件事

附录:RxJS Multicast 类 Operator (1) - multicast / publish / refCount / share / shareReplay


<<:  Day17-维稳? StatefulSet介绍

>>:  DAY 13 『 Realm 新增、修改、删除 』Part1

[Day 28] 永和美食纪录-翻转屋 锅烧意面

前言 铁人赛已经进入最後的倒数阶段,看着版上有许多钻研着专业领域的前辈们陆陆续续地完成挑战,笔者真的...

Swift纯Code之旅 Day19. 「ViewController好乱(1) - MVC介绍)」

前言 做到现在会发现每个ViewController内的程序码都一大堆,有画面元件,有逻辑,有Mod...

[第二天]从0开始的UnityAR手机游戏开发-如何安装Unity Hub与申请Unity和Vuforia的帐号

安装Unity Hub 请到Unity的官网下载页面 https://unity3d.com/ge...

【Day 29】实作 - 如何设定 AWS CloudWatch Alarms

昨天我们讨论到我们可以从 AWS console 的 EC2 服务查看 Instance statu...

30天学会 Python-Day28: 选择档案

tkinter tkinter 是 Python 中用於制作 GUI 的套件 可以用 tkinter...