首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >1:N或N:1 Angular2中的两个对象之间的关系是从http请求中观察到的

1:N或N:1 Angular2中的两个对象之间的关系是从http请求中观察到的
EN

Stack Overflow用户
提问于 2017-03-31 12:42:06
回答 1查看 3K关注 0票数 7

引用角教程中的"英雄之旅“。

假设我们会给所有现存的英雄穿上一套特别的套装,但是任何其他的英雄也可以穿同一套。我们真的不想让他们裸体。在这种情况下,我们将有一个相关的数据对象,它保存关于可用西装的所有信息。英雄本身必须知道他穿的是哪一套套房,以及他在哪里可以找到他选定的一套。在这种情况下,我们将创建一个属性来保存他选择的衣服的ID。

从http请求中可以观察到,怎样才能正确地解决英雄和他的套间之间的关系?

例如:

app/hero.ts

代码语言:javascript
复制
export class Hero {
  id: number;
  name: string;
  suiteId: number;
}

app/suit.ts

代码语言:javascript
复制
export class Suite {
  id: number;
  name: string;
  material: string;
  color: string;
}

app/in-memory-data.service.ts

代码语言:javascript
复制
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};
  }
}

我知道下一个代码块会起作用,但我想知道如何以“可观察”的方式解决这个问题。

代码语言:javascript
复制
// ...
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);
}
// ...
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-03 12:18:34

getHeroesWithSuit()方法执行两个任务。

  1. 把英雄名单拿出来。
  2. 获取每个英雄的套间细节。

当我们想要组合这两个操作时,我们需要使用flatMapforkJoin运算符。使用这两个操作符,getHeroesWithSuit()函数可以像这样以可观察的方式编写。

代码语言:javascript
复制
    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。

然后,我们将每个英雄映射到suiteServicessuiteServices方法,并将结果传递给forkJoin操作符。

上面的代码片段表示N:1关系,其中每个英雄都有一个套件。

但是,如果每个英雄都有多个套件,而suiteId字段的Hero类是一个Array.In,那么我们必须再次使用forkJoin操作符来检索每个英雄的所有套件的信息。

在这个forkJoin中,我们将把每个英雄的所有suiteId映射到suiteServicesgetSuit()方法。这将是1:n objects.The更新getHeroesWithSuit()函数之间的关系,如下所示。

代码语言:javascript
复制
  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;
              })
          }
        ))
      );
  }

这里是参考链接,它很好地解释了操作符,以及如何使用它们来组合多个可观测的。我希望这能帮上忙。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43140979

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档