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
相关产品推荐
相关产品推荐

