javascript - 在 Angular 中使用 Rxjs 更新来自不同 Json 源的 Json 中的数据
问题描述
我有 3 种不同的服务 A、B、C。这些服务各自生成不同的 JSON。来自服务 A 的 JSON 具有需要用来自 JSON B 和 C 的值替换的值的属性。
我已经使用纯 JavaScript 解决了这个问题,但我想使用 Rxjs,因为 Rxjs 是可扩展的。我想返回一个 Observable 而不是数据。
我的三个 JSON:
let A = {
"conditions": [{
"conditionId": "BASFD",
"conditionDescr": "Substitute with component description",
"pay": "P"
}, {
// << more items >>
}]
};
let B = {
"components": [{
"componentId": "BASFD",
"description": "Assortimentsbonus"
}, {
"componentId": "BBY",
"description": "Bonus bypass"
}]
};
let C = {
"text": [{
"textcode": "PAYMENT",
"values": [{
"code": "P",
"description": "Percentage"
}, {
"code": "A",
"description": "Amount"
}]
}, {
"textcode": "PERIOD",
"values": [{
"code": "J",
"description": "Per year"
}, {
"code": "M",
"description": "Per month"
}]
}]
}
我的 JavaScript 代码替换值ConditionDescr
和Pay
JSON A:
this.httpClient.get<ConditieTypeObject>(environment.url + 'bonus/' + id, {
params: new HttpParams().append('year', year.toString()),
observe: 'body',
responseType: 'json'
}).pipe(map(x => x.conditions)).subscribe((A) => {
A.forEach((y) => {
y.conditionDescr = B.components.filter(function (x2) {
return x2.componentId == y.conditionId;
})[0].description;
y.pay = C.text.filter(function (x3) {
return x3.textcode == 'PERIOD';
})[0].values.filter(function (x4) {
return x4.code == y.pay;
})[0].description;
});
console.log(A);
});
然后结果就是这样,没关系:
{
"conditions": [{
"conditionId": "BASFD",
"conditionDescr": "Assortimentsbonus",
"pay": "Per year"
}, {
// << more items >>
}]
}
但是我想在 Rxjs 中解决这个问题,因为我可以使用一个 observable,它可以直接作为异步传递给 HTML 表。我不想像现在在我的代码中那样先订阅该函数。
我试过了switchMap
,concatMap
但这不起作用。有人知道如何在 RxJS 中解决这个问题吗?
解决方案
您可以使用pipe()
RxJS将您的三个服务请求组合成一个 Observable。然后可以将此 Observable 分配给组件类中的变量,并使用模板中的异步管道进行引用。map()
combineLatest
在您的 component.ts 中:
import { Component, OnInit } from '@angular/core';
import * as fromServices from './services';
import { combineLatest, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
export class ExampleComponent implements OnInit {
// 1. Create a new reference for an Observable that will contain your final data.
finalData$: Observable<any[]>;
constructor(
// 2. Include your various services in your component.
private aService: fromServices.AService,
private bService: fromServices.BService,
private cService: fromServices.CService,
) {}
ngOnInit(): void {
// 3. Initialise the Observables from your services in an Array passed into combineLatest.
this.finalData$ = combineLatest([
this.aService.data$,
this.baService.data$,
this.cService.data$,
])
// 4. Map over each Observable.
.pipe(map(([aData, bData, cData]) => {
// 5. Transform your data. Note: Your Observable must return a value for it to emit a value.
return aData.filter(() => { /* ... */ });
}));
}
}
在您的 component.html 中:
<!-- 6. Use the async pipe to subscribe to this data. -->
<p *ngFor="let data of {{ finalData$ | async }}">{{ data.propertyName }}</p>
推荐阅读
- php - 如何在 postgresql 执行时获取违反列名的唯一键
- amazon-web-services - 避免从一个 lambda 到另一个的异步调用
- pandas - pandas df列系列
- java - 部署几天后 Hikari CP Java springboot getConnection 错误
- apache-nifi - 为什么 logback.xml 在 Nifi 中工作,与设置不同?
- django - Django - 如何根据当前登录的用户在管理面板中默认填充模型的用户字段?
- c# - trackrevisions 方法或属性不可用,因为此命令不可读取
- c# - 将文本从表单传递到公式字段
- c - 无法使用 while(1) 循环遍历双向链表 - 分段错误
- asp.net - 尝试在浏览器中预览 ASPX 文件时出现解析器错误和/或编译器错误