RxJS中基于API返回值过滤Observable数据并在Angular模板展示的问题求助
RxJS中基于API返回值过滤Observable数据并在Angular模板展示的问题求助
我是RxJS新手,希望能得到大家的帮助!
我想在Angular组件的HTML模板里生成一个单选按钮列表,列表数据来自Observable,通过async管道获取。
现有可正常工作的代码
模板部分
<div *ngIf="entities$ | async as entities"> <mat-radio-group aria-labelledby="entities-radio-group-label" class="entities-radio-group" > <mat-radio-button *ngFor="let entity of entities" [value]="entity"> {{entity.description}} </mat-radio-button> </mat-radio-group> </div>
组件类部分
组件里有一个从服务获取实体数据的Observable,并且已经按实体类型过滤出了SET类型的实体:
entities$: Observable<Entity[]> = this.eventsService.entities$ .pipe( map(items => items.filter(item => item.type.toLowerCase().indexOf("set") > -1)), );
实体数据结构
获取到的实体数组结构如下:
[ {"id":"34534534643364", "type":"SET", "description":"some description", "link":"/conf/sets/34534534643364"}, {"id":"5474745744457547", "type":"SET", "description":"other description", "link":"/conf/sets/5474745744457547"} ]
需要解决的问题
现在我需要基于每个实体link字段对应的API返回值,对实体列表做额外过滤。具体来说,调用每个实体的link接口后,要获取返回数据中的content.desc值,再根据这个值来筛选实体。
API调用方式及返回结构
我用服务发起API请求的代码如下:
this.restService.call<any>(entityUrl) .pipe(finalize(()=>this.loading=false)) .subscribe( apidata => console.log(`data: ${JSON.stringify(apidata)}`), error => this.alert.error('Failed to retrieve entity: ' + error.message) );
API返回的数据结构:
{ "id": "34534534643364", "name": "some name", "description": null, "type": { "value": "LOGICAL", "desc": "Logical" }, "content": { "value": "IEP", "desc": "This it the value I need" }, "status": { "value": "ACTIVE", "desc": "Active" } }
我需要用content.desc的值来判断是否保留对应的实体。
尝试过但失败的方法
我尝试在Observable管道里添加自定义过滤函数,但因为API请求是异步的,函数无法等到请求完成就返回了结果,导致过滤逻辑失效。
修改后的Observable代码
entities$: Observable<Entity[]> = this.eventsService.entities$ .pipe( tap((items) => console.log("started pipe", items)), map(items => items.filter(item => item.type.toLowerCase().indexOf("set") > -1)), tap((items) => console.log("after set filtered pipe", items)), map(items => items.filter(item => this.descFilter(item.link))), tap((items) => console.log("after descFilter: ", items)), tap(() => this.clear()) );
自定义过滤函数
descFilter(link: string): boolean{ let testedEnt:any = []; const resObs$ = this.restService.call<any>(link) .pipe(finalize(()=>this.loading=false)) .subscribe( next => { console.log(`checkTitleSet api call result:, ${JSON.stringify(next)}`); testedEnt = next.content.desc; console.log("desc from inside next: ",testedEnt); // 这里能正确拿到值 }, error => this.alert.error('Failed to retrieve entity: ' + error.message) ); console.log("desc: ",testedEnt); // 这里拿不到值,因为请求还没完成 return testedEnt === "some string"; }
另一个思路但卡壳了
我还想过直接用所有API请求的返回结果来生成模板里的单选列表,并且已经创建了一个包含所有API请求Observable的数组,但不知道怎么在模板里使用这个数组来渲染内容。
真心希望大家能给我一些可行的建议,谢谢!
备注:内容来源于stack exchange,提问作者hagay bar
相关产品推荐
相关产品推荐

