我们有一个与前端无关的REST-API,这意味着它始终将IRI发送到其嵌套资源。因此,要检索某些数据,您始终必须进行多个http调用(首先获取父资源,然后获取其子资源,等等)。 因此,每个国家/地区都有一个链接条目列表。每个条目都链接到一个产品,该产品的类别资源具有IRI。
export interface Country {
countryId: number;
name: string;
code: string;
projects: string[]; //contains an array of IRIs for the project resources
entries: string[];
}
export interface Entry {
entryId: number,
country: string,
information: string,
strategy: string,
action: string,
user: string,
product: string,
salesStatus1: string,
salesStatus2: string,
salesStatus3: string,
salesStatus4: string,
salesStatus5: string,
}
export interface Product {
productId: number,
productName: string,
sharepointId: string,
category: string,
plmId: string,
productStatus1: string,
productStatus2: string,
productStatus3: string,
productStatus4: string,
productStatus5: string,
productComponents: string[]
}
export interface Category {
categoryId: number,
name: string,
children: string[]
}
export class Node {
children: Node[] = [];
name: string;
isProduct: boolean;
}
因此,为了使用显示导航树所需的所有数据,我编写了以下代码:
ngOnInit() {
let nodes: Node[] = new Array<Node>();
this.countriesService.getAll()
.subscribe(
(countries) => {
for (let country of countries) {
let countryNode = new Node();
countryNode.name = country.name;
countryNode.isProduct = false;
for (let entryUrl of country.entries) {
this.entriesService.getByUrl(entryUrl).subscribe(
(entry) => {
this.productsService.getByUrl(entry.product).subscribe(
(product) => {
this.categoryService.getByUrl(product.category).subscribe(
(category) => {
let categoryNode = new Node();
categoryNode.name = category.name;
categoryNode.isProduct = true;
countryNode.children.push(categoryNode);
for (let childrenUrl of category.children) {
this.categoryService.getByUrl(childrenUrl).subscribe(
(childCategory) => {
let categoryChildNode = new Node();
categoryChildNode.name = childCategory.name;
categoryChildNode.isProduct = false;
categoryNode.children.push(categoryChildNode);
}
)
}
}
)
}
)
}
)
}
nodes.push(countryNode);
}
this.dataChange.next(nodes);
}
);
}
但是,由于我是Angular和rxjs的新手,因此我遇到了“等待”问题,直到所有调用完成并且所有数据(由于其异步)在那里(因此导航树始终会丢失元素)。像这样进行链接也很丑陋和不好的做法。所以我想重构 rxjs方法的代码,但是我完全迷失了如何开始使用它,因为检索数据后,我必须再次对其进行迭代以获取嵌套的资源IRI,还必须为树导航创建Node对象。 / p>
您能否在重构该代码方面给我一些帮助?
答案 0 :(得分:0)
不确定这是否有帮助,我将请求与rxjs运算符组合在一起。
this.countriesService.getAll()
.pipe(
map((cs) => forkJoin(cs.map(c => {
const countryNode = new Node();
countryNode.name = c.name;
countryNode.isProduct = false;
return forkJoin(c.entries.map(entryUrl => this.entriesService.getByUrl(entryUrl)))
.pipe(
switchMap(entries => forkJoin(entries.map(entry => this.productsService.getByUrl(entry.product)))),
switchMap(products => forkJoin(products.map(product => this.categoryService.getByUrl(product.category)))),
switchMap(categories => forkJoin(categories.map(category => {
const categoryNode = new Node();
categoryNode.name = category.name;
categoryNode.isProduct = true;
return forkJoin(category.children.map(childrenUrl => this.categoryService.getByUrl(childrenUrl)))
.pipe(
map(cc => {
categoryNode.children = cc.map(childCategory => {
const categoryChildNode = new Node();
categoryChildNode.name = childCategory.name;
categoryChildNode.isProduct = false;
return categoryChildNode;
});
return categoryNode;
})
);
}))),
map(categoryNodes => {
countryNode.children = categoryNodes;
return countryNode;
})
);
})))
).subscribe(countryNodes => {
this.dataChange.next(countryNodes)
});