2017-03-31 3 views
4

각도 자습서의 "Tour of heroes"을 참조하십시오.http : // 요청에서 Observable로 Angular2에있는 두 개체의 N 또는 N : 1 관계

기존의 모든 영웅에게 특별한 스위트를 착용 할 수 있다고 가정했지만 다른 영웅도 같은 스위트를 착용 할 수 있다고 가정합니다. 우리는 정말로 그들이 벗은 채로 있기를 원하지 않습니다. 이 경우 사용 가능한 슈트에 대한 모든 정보를 보유하고있는 관련 데이터 객체를 갖게됩니다. 영웅 그 자체는 그가 입고있는 스위트와 그가 선택한 것을 찾을 수있는 곳을 알아야합니다. 이 경우 우리는 자신이 선택한 복장의 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); 
} 
// ... 
+0

어디에서 'getHeroesWithSuit'가 필요합니까? 여기에 논리가 뭐니? 실례지만 뭔가 명확하지는 않지만 질문이 조금 애매한 것 같습니다. 내가 이해 한 것은 '영웅'과 '복장'이 있다는 것입니다. '정장 '에는'id'가 있고'id'를'영웅들'에게 할당합니다. 그리고 뭐? – echonax

+0

기술적으로, 어디서 getHeroesWithSuit 메소드를 호출 할 것인가는 문제가되지 않는다. 아마도 컴포넌트로부터의 요청에 대한 데이터를 제공하는 서비스 일 것이다. 일부 영웅이 세부 및 목록 구성 요소에 입고있는 소송을 표시하려고한다고 가정합니다. 이 주제가 일반적이기 때문에이 질문은 모호합니다. – Daniel

답변

5

방법 getHeroesWithSuit()은 두 가지 작업을 수행합니다.

  1. 영웅의 목록을 얻으십시오.
  2. 각 영웅에 대한 세부 정보를 가져옵니다.

우리는이 두 작업을 결합하기 위해 flatMapforkJoin 연산자를 사용해야합니다. 이 두 연산자를 사용하여 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; 
      }); 
     })) 
     ); 
    } 

flatMap 운영자는 새 관찰 가능한 반환,이 Observable 인을 체인 수 있습니다. 여기서 우리는 영웅 검색 서비스의 결과를 forkJoined observable에 연결합니다.

그리고 나서 우리는 suiteServicesgetSuite() 방법으로 각 영웅을 매핑하고 그 결과를 forkJoin 연산자로 전달했습니다.

위의 코드 스 니펫은 N : 1 릴레이션을 나타내며, 각 영웅마다 하나의 세트가 있습니다.

하지만 각 영웅은 여러 개의 스위트 룸을 가지고 있으며, Hero 클래스의 suiteId 필드가 Array.In 우리가 각 영웅에 대한 모든 스위트 룸의 정보를 검색 할 수 forkJoin 운영자를 한 번 더 사용해야 할 경우 경우.

forkJoin에서 각 영웅의 모든 suiteIdgetSuit() 방법으로 매핑합니다 (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; 
       }) 
      } 
     )) 
    ); 
    } 

reference link이 좋은 운영자의 설명과 방법을 여러 관찰 가능한 결합하는 데 사용할 방법을 가지고있다. 이것이 도움이되기를 바랍니다.

+0

답변 해 주셔서 감사합니다! N : 1 관계 (많은 영웅들이 똑같은 옷을 입을 수 있음)을 묘사하고 있다고 생각해보십시오. 다른 방향은 어떻게 생겼습니까? 나는 1 : N을 의미합니다 (한 영웅은 정장의 많은 부분을 예를 들어 장갑, 티셔츠 등). 물론'suitId : [1,2,3]'은 배열이어야합니다. 다음은 무엇입니까? 나는 나중에 내 질문을 업데이트 할 것이다. – Daniel

+0

잘, 1 : N 관계에 대해 우리는 각 영웅에 대한 모든 스위트 정보를 검색하기 위해 포크 조인을 하나 더 가질 수 있습니다. 내 대답을 업데이트 중입니다. – HirenParekh

+0

1 : N 관계 시나리오를 설명하는 해답을 업데이트했습니다. – HirenParekh