Angular 11 RxJS 如何向Observable对象的嵌套列表中添加新元素?
实现方案
核心逻辑:普通Observable是只读数据流,无法直接修改其发射的值,你需要搭配BehaviorSubject作为状态容器存储原始数据,对外暴露Observable供async管道订阅,更新时主动发射新值即可触发页面自动刷新。
步骤1:调整状态定义
替换你原来直接定义的invoices$,底层用BehaviorSubject存储最新的发票数据:
import { BehaviorSubject } from 'rxjs'; // 私有状态容器,存储最新的发票数据,初始值可根据你的业务设置为null或者初始获取的发票对象 private invoicesSubject = new BehaviorSubject<Invoice | null>(null); // 对外暴露的Observable,模板中用法和你原来的invoices$完全一致 invoices$ = this.invoicesSubject.asObservable();
你首次从接口获取发票数据时,需要手动把数据同步到Subject中:
// 示例:接口获取发票数据后的回调 this.invoiceApi.getInvoiceById(invoiceId).subscribe(invoice => { this.invoicesSubject.next(invoice); });
步骤2:新增行项目后更新状态
你把新行项目保存到数据库成功后,生成全新的发票对象(不能修改原对象引用,否则async管道无法检测到变化),然后通过Subject发射新值即可:
// 新增行项目成功后的回调 onLineItemSaved(newLineItem: InvoiceLineItem) { const currentInvoice = this.invoicesSubject.value; // 安全校验,避免当前无发票数据时报错 if (!currentInvoice) return; // 生成全新的发票对象,所有修改的字段都要做浅拷贝 const updatedInvoice = { ...currentInvoice, // 行项目数组也要生成新数组,不要直接push原数组 invoiceLineItems: [...currentInvoice.invoiceLineItems, newLineItem], // 按需同步更新发票总金额 fdTotal: currentInvoice.fdTotal + newLineItem.fdItemTotal }; // 发射更新后的发票数据,async管道会自动接收新值刷新页面 this.invoicesSubject.next(updatedInvoice); }
注意事项
- 模板部分不需要做任何修改,你原来的
*ngIf="invoices$ | async as invoices"写法可以直接沿用 - 不要直接修改
invoicesSubject.value的属性,也不要直接给invoiceLineItems数组push元素,必须生成新的对象/数组,否则变更检测不会触发 - 如果你的
invoices$是多发票数组,逻辑完全一致,只需要修改拷贝时的逻辑,找到对应要更新的发票对象替换即可
内容的提问来源于stack exchange,提问作者John Chandler
相关产品推荐
相关产品推荐

