Dan*_*iel 6 rest observable rxjs typescript angular
参考角度教程中的" 英雄之旅 ".
假设我们将给所有现有英雄穿上特殊套件的可能性,但任何其他英雄也可以穿同一套房.我们真的不希望他们赤身裸体.在这种情况下,我们将有一个相关的数据对象,其中包含有关可用套装的所有信息.英雄本身必须知道他穿着哪个套房以及在哪里可以找到他所选择的套房.对于这种情况,我们将创建一个属性,其中包含所选服装的ID.
从http请求中可以观察到解决Angular中英雄和他的套件之间关系的正确方法是什么?
例如:
app/hero.ts
export class Hero {
id: number;
name: string;
suiteId: number;
}
Run Code Online (Sandbox Code Playgroud)
app/suit.ts
export class Suite {
id: number;
name: string;
material: string;
color: string;
}
Run Code Online (Sandbox Code Playgroud)
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};
}
}
Run Code Online (Sandbox Code Playgroud)
我知道下一个代码块之类的东西会起作用,但我想知道如何解决这个"可观察"的方式.
// ...
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);
}
// ...
Run Code Online (Sandbox Code Playgroud)
该方法getHeroesWithSuit()完成两项任务.
因为我们想要结合这两个操作,我们需要使用flatMap和forkJoin运算符.使用这两个运算符getHeroesWithSuit()函数可以用这样的Observable方式编写.
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;
});
}))
);
}
Run Code Online (Sandbox Code Playgroud)
flatMap运算符允许您链接两个Observable,返回一个新的Observable.这里我们将检索英雄服务的结果链接到forkJoined observable.
然后我们将每个英雄映射到该getSuite()方法suiteServices并将结果传递给forkJoin运算符.
上面的代码片段代表N:1关系,其中每个英雄都有一个套件.
但是,如果每个英雄有多个套件,并且类的suiteId字段Hero是一个数组.在这种情况下,我们必须再次使用forkJoin运算符来检索每个英雄的所有套件的信息.
在这里,forkJoin我们将suiteId每个英雄的所有地图映射到getSuit()方法suiteServices.这将是对象之间的1:N关系.更新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;
})
}
))
);
}
Run Code Online (Sandbox Code Playgroud)
这里是参考链接,它对运算符有很好的解释,以及如何使用它们来组合多个Observable.我希望这将有所帮助.
| 归档时间: |
|
| 查看次数: |
2196 次 |
| 最近记录: |