如何过滤Google Firestore Observable?Angular开发求助
解决Firestore Observable过滤下拉选择结果的问题
首先看你之前的过滤代码,问题出在这两点:
- 你先执行了
map(aaa => {return aaa.map(bbb => ())}),这个操作把原始的发票数组转换成了空函数组成的数组,完全丢失了发票数据,后面的filter(flt => flt.key === this.sID)自然会报错——空函数根本没有key属性。 - 逻辑顺序也错了,应该先从数组里筛选出匹配的元素,而不是先做无效的map转换。
正确的过滤实现
我们先定义一个发票类型(帮助TypeScript更好地推断类型,避免类似的属性不存在错误):
interface Invoice { key: string; invNo: string; // 加上你实际用到的其他字段 }
然后修改你的getInv方法,正确过滤Observable中的数据:
getInv(e) { this.sID = e.value; // 获取选中发票的ID // 从发票列表Observable中过滤出选中的那一项 this.invList.pipe( // 先从数组里找到key匹配的发票 map(invoices => invoices.find(invoice => invoice.key === this.sID)), // 过滤掉找不到匹配项的情况(可选) filter(selectedInv => !!selectedInv) ).subscribe(selectedInv => { console.log(selectedInv.invNo); }); }
额外优化建议
不要直接访问
source属性:你之前的this.invList = this.invoices.source;其实没必要,shareReplay(1)已经让this.invoices成为可共享的Observable了,直接设置this.invList = this.invoices;就足够,避免依赖RxJS内部的source属性(不同版本可能有变化)。用响应式方式处理选中结果:手动订阅容易导致内存泄漏,更好的做法是定义一个Observable来保存选中的发票,然后在模板中用
asyncpipe:
// 组件中定义 selectedInvoice$: Observable<Invoice | undefined>; getInv(e) { this.sID = e.value; this.selectedInvoice$ = this.invoices.pipe( map(invoices => invoices.find(inv => inv.key === this.sID)) ); }
模板中使用:
<div *ngIf="selectedInvoice$ | async as selectedInv"> 选中的发票编号:{{selectedInv.invNo}} </div>
这样既符合Angular响应式编程的最佳实践,又能自动管理订阅,避免内存泄漏。
内容的提问来源于stack exchange,提问作者quince
相关产品推荐
相关产品推荐

