引用角教程中的"英雄之旅“。
假设我们会给所有现存的英雄穿上一套特别的套装,但是任何其他的英雄也可以穿同一套。我们真的不想让他们裸体。在这种情况下,我们将有一个相关的数据对象,它保存关于可用西装的所有信息。英雄本身必须知道他穿的是哪一套套房,以及他在哪里可以找到他选定的一套。在这种情况下,我们将创建一个属性来保存他选择的衣服的ID。
从http请求中可以观察到,怎样才能正确地解决英雄和他的套间之间的关系?
例如:
app/hero.ts
export class Hero {
id: number;
name: string;
suiteId: number;
}app/suit.ts
export class Suite {
id: number;
name: string;
material: string;
color: string;
}app/in-memory-data.service.ts
import { InMemoryDbService } from 'angular-in-memory-web-api';
export class InMemoryDataService implements InMemoryDbService {
createDb() {
let heroes = [
{id: 11, name: 'Mr. Nice', suitId: 11},
{id: 12, name: 'Narco', suitId: 12}
];
let suits= [
{id: 11, name: 'Nice and blue', material: 'Cotton', color: 'blue'},
{id: 12, name: 'Sexy and red', material: 'Silk', color: 'red'}
];
return {heroes, suits};
}
}我知道下一个代码块会起作用,但我想知道如何以“可观察”的方式解决这个问题。
// ...
getHeroesWithSuit(): Observable<Hero[]> {
return this.http.get(this.heroesUrl)
.map( response => response.json().data as Hero[])
.do( response => response.forEach( ( data ) => data.suite = this.suiteService
.getSuit(data.suiteId)
.subscribe(suite => data.suite = suite as Suite)
))
.catch(this.handleError);
}
// ...发布于 2017-04-03 12:18:34
getHeroesWithSuit()方法执行两个任务。
当我们想要组合这两个操作时,我们需要使用flatMap和forkJoin运算符。使用这两个操作符,getHeroesWithSuit()函数可以像这样以可观察的方式编写。
getHeroesWithSuit(): Observable<Hero[]> {
return this.http.get(this.heroesUrl)
.map(response => response.json().data as Hero[])
.flatMap((heroes: Heroes[]) => Observable.forkJoin(heroes.map((hero: Hero) => {
return this.suiteService.getSuit(hero.suiteId)
.map((suite: Suite) => {
hero.suite = suite;
return hero;
});
}))
);
}flatMap操作符允许您链接两个可观测值,返回一个新的可观测值。在这里,我们将检索英雄服务的结果链接到可观察到的forkJoined。
然后,我们将每个英雄映射到suiteServices的suiteServices方法,并将结果传递给forkJoin操作符。
上面的代码片段表示N:1关系,其中每个英雄都有一个套件。
但是,如果每个英雄都有多个套件,而suiteId字段的Hero类是一个Array.In,那么我们必须再次使用forkJoin操作符来检索每个英雄的所有套件的信息。
在这个forkJoin中,我们将把每个英雄的所有suiteId映射到suiteServices的getSuit()方法。这将是1:n objects.The更新getHeroesWithSuit()函数之间的关系,如下所示。
getHeroesWithSuit():Observable<Hero[]> {
return this.http.get(this.heroesUrl)
.map(response => response.json().data as Hero[])
.flatMap(
(heroes:Heroes[]) => Observable.forkJoin(heroes.map(
(hero:Hero) => {
return Observable.forkJoin(hero.suiteIds.map(
suiteId => {
return this.suiteService.getSuit(suiteId)
}
)).map(
suites => {
hero.suites = suites;
return hero;
})
}
))
);
}这里是参考链接,它很好地解释了操作符,以及如何使用它们来组合多个可观测的。我希望这能帮上忙。
https://stackoverflow.com/questions/43140979
复制相似问题