如何获取Observable中的最后一个id值并传入FormBuilder?
问题
我有如下Observable数据:
{ name: Jack, id: 1} { name: Albert, id: 2}, { name: Johnny, id: 3}
想要新增下一条数据,必须读取最后一个id值(此场景中为3)。
我尝试了以下代码:
id$ = this.comapniesService.getCompaniesInfos().pipe( map(res => res.map(res => { return res.company_id; }) ) ); id2 = []; id = this.id$.subscribe(res => { return this.id2.push(res); });
在HTML中能正确显示数组:
<pre> {{ id2 }} <!-- Display [1, 2, 3] --> </pre> 但当我尝试将其加入FormBuilder时: ```typescript private buildForm() { this.form = this.formBuilder.group({ // 其他字段...... company_id: this.id2.length // DISPLAY 0 }); }
我还做了如下测试:
ngAfterViewInit() { console.log(this.id2); // Display [1,2,3] console.log(this.id2[2]); // Display undefined console.log('this.id2.length'); // Display 0 }
请问如何获取Observable中的最后一个id数据并传入FormBuilder?
解决方法
核心问题是Observable是异步的,你调用buildForm的时候,id$的订阅还没完成,所以id2还是空数组。下面是几个可行的方案:
方案1:在订阅回调里构建表单
把buildForm移到订阅的回调函数中,确保拿到数据后再初始化表单:
id$ = this.comapniesService.getCompaniesInfos().pipe( map(res => res.map(item => item.company_id)) ); // 不要提前调用buildForm,等数据回来再处理 this.id$.subscribe(ids => { // 拿到所有id数组后,取最后一个值 const lastId = ids.length > 0 ? ids[ids.length - 1] : 0; // 在这里构建表单 this.buildForm(lastId); }); private buildForm(lastId: number) { this.form = this.formBuilder.group({ // 其他字段 company_id: [lastId + 1] // 新增数据的id可以直接用lastId+1 }); }
方案2:直接获取最后一个id的Observable
先通过RxJS操作符提取出最后一个id,再订阅它来构建表单:
// 直接获取最后一个id的Observable lastCompanyId$ = this.comapniesService.getCompaniesInfos().pipe( map(res => { const ids = res.map(item => item.company_id); return ids.length > 0 ? ids[ids.length - 1] : 0; }) ); // 在组件初始化时订阅这个Observable来构建表单 ngOnInit() { this.lastCompanyId$.subscribe(lastId => { this.buildForm(lastId); }); } private buildForm(lastId: number) { this.form = this.formBuilder.group({ // 其他字段 company_id: [lastId + 1] }); }
方案3:用操作符串联数据流(推荐)
用tap等操作符串联数据流,减少手动订阅带来的异步问题:
ngOnInit() { this.comapniesService.getCompaniesInfos().pipe( map(res => { const ids = res.map(item => item.company_id); return ids.length > 0 ? ids[ids.length - 1] : 0; }), // 拿到最后一个id后直接构建表单 tap(lastId => this.buildForm(lastId)) ).subscribe(); } private buildForm(lastId: number) { this.form = this.formBuilder.group({ // 其他字段 company_id: [lastId + 1] }); }
补充说明
你之前测试中console.log(this.id2)显示[1,2,3]但length是0,是因为浏览器控制台会异步更新数组的显示,实际执行console.log('this.id2.length')时数组还没被填充。
内容的提问来源于stack exchange,提问作者Mic P
相关产品推荐
相关产品推荐

