You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular Firestore中实现ngIf-else结合ngFor单次显示OWNED或购买按钮

解决Firestore集合中判断文档是否已购买并只显示单个按钮的问题

你的问题根源在于用*ngFor遍历了整个studyList数组,每遇到一个和目标documentId不匹配的文档,就会渲染一次Buy按钮——这就导致了按钮重复显示。我们需要的是一次性判断整个数组里是否存在目标文档,而不是逐个遍历判断。

这里给你两种简洁的解决方案:


方案1:组件内封装判断方法(推荐,模板更简洁易维护)

首先在你的组件.ts文件里添加一个判断用户是否拥有该文档的方法:

hasDocument(documentId: string): boolean {
  // 使用可选链避免user或studyList为空时的报错,some方法只要有一个匹配就返回true
  return this.user?.studyList?.some(doc => doc.id === documentId) || false;
}

然后修改模板代码,去掉*ngFor,直接用这个方法做判断:

<div class="col-md-2">
  <ng-container *ngIf="hasDocument(documentId); else buyButton">
    <button class="btn btn-large" disabled>Owned</button>
  </ng-container>
  <ng-template #buyButton>
    <button class="btn btn-large" (click)="addToStudyList(user)">Buy</button>
  </ng-template>
</div>

方案2:直接在模板中使用数组some方法

如果不想额外写组件方法,也可以直接在模板里用some方法一次性判断:

<div class="col-md-2">
  <button class="btn btn-large" disabled *ngIf="user.studyList?.some(doc => doc.id === documentId)">Owned</button>
  <button class="btn btn-large" (click)="addToStudyList(user)" *ngIf="!(user.studyList?.some(doc => doc.id === documentId))">Buy</button>
</div>

为什么原来的写法会重复显示按钮?

原来的*ngFor会循环studyList的每一项:

  • 每遇到一个匹配documentId的项,就渲染Owned按钮
  • 每遇到一个不匹配的项,就渲染Buy按钮

这就导致如果用户的studyList里有N个和目标文档无关的项,就会显示N个Buy按钮。而我们需要的是基于整个数组的判断结果,只渲染一个按钮,上面的两种方案都能实现这个效果。

内容的提问来源于stack exchange,提问作者Andreea Popa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 18:32:40