2016-07-21 1 views
0

Я пытаюсь сделать простую связь между угловым компонентом 2 и сервисом, но я не могу понять, как это сделать с помощью Observable.Двусторонняя привязка между угловым компонентом 2 и сервисом с использованием Observable

Мой компонент HeroViewerComponent поддерживает параметр маршрутизатора id и передает его в службу HeroService получить Hero когда услуга получить его с сервера. HeroService имеет метод, называемый getHeroSubscription, который принимает Observable<number> в качестве параметра и возвращает Observable<Hero>. Но это не сработает.

Вот мой HeroViewerComponent в hero-viewer.component.ts:

import { Component, OnInit, OnDestroy } from "@angular/core"; 
import { ActivatedRoute } from "@angular/router"; 
import { Observable } from "rxjs/Observable"; 
import { Observer } from "rxjs/Observer"; 
import { Subscription } from "rxjs/Subscription"; 

import { HeroService } from "./hero.service"; 
import { Hero } from "./hero"; 

@Component({ 
    providers: [HeroService] 
}) 
export class HeroViewerComponent implements OnInit, OnDestroy { 
    private routeParamsSubscription:Subscription; 

    // to the service 
    private routeParamsObservable:Observable<number>; 

    // the subscriber of the route ID param 
    private routeParamsObserver:Observer<number>; 

    // from the service 
    private heroSubscription:Subscription; 

    // the current hero 
    hero:Hero; 

    constructor(private route:ActivatedRoute, private heroService:HeroService) {} 

    ngOnInit() { 
     this.routeParamsObservable = new Observable<number>((observer:Observer<number>) => this.routeParamsObserver = observer); 

     this.heroSubscription = this.heroService 
      .getHeroSubscription(this.routeParamsObservable) 
      .subscribe(
       hero => this.hero = hero, 
       error => console.warn(error) 
      ); 

     this.routeParamsSubscription = this.route 
      .params 
      .subscribe(
       params => this.routeParamsObserver.next(+params["id"]), 
       error => console.warn(error) 
      ); 
    } 

    ngOnDestroy() { 
     this.routeParamsSubscription.unsubscribe(); 
     this.heroSubscription.unsubscribe(); 
     this.routeParamsObserver.complete(); 
    } 
} 

Вот мой HeroService в hero.service.ts:

import { Injectable } from "@angular/core"; 
import { Http, Response } from "@angular/http"; 
import { Observable } from "rxjs/Observable"; 
import { Observer } from "rxjs/Observer"; 
import "rxjs/add/operator/merge"; 
import "rxjs/add/operator/map"; 
import "rxjs/add/observable/throw"; 
import "rxjs/add/operator/catch"; 

import { Hero } from "./hero"; 

@Injectable() 
export class HeroService { 
    constructor(private http:Http) {} 

    getHeroSubscription(heroIdObservable:Observable<number>):Observable<Hero> { 
     let heroObserver:Observer<Hero>; 
     let heroObservable = new Observable<Hero>((observer:Observer<Hero>) => { 
      heroObserver = observer; 
     }); 

     let heroIdSubscription = heroIdObservable.subscribe(
      heroId => { 
       const tmp = this.http 
        .get("api/heroes/" + heroId) 
        .map((response:Response) => response.json().data) 
        .catch((response:any) => { 
         if (response instanceof Response) { 
          return Observable.throw(response.json().error); 
         } 
         return Observable.throw(response); 
        }); 
       heroObservable.merge(tmp); 
      }, 
      error => console.warn(error), 
      () => { 
       heroIdSubscription.unsubscribe(); 
       heroObserver.complete(); 
      } 
     ); 

     return heroObservable; 
    } 
} 

А вот мой Hero в hero.ts:

export class Hero {public id: number;} 

Где м Я ошибаюсь?

+1

Почему вы подписавшись на параметр маршрута? Я не уверен, что понял вашу цель здесь. –

+0

Станьте я привязываю 'HeroViewerComponent' к маршруту' heroes /: id', чтобы этот параметр можно было изменить без разрушения компонента. Например, я нахожусь на маршруте 'heroes/10043' и' HeroViewerComponent' рендеринга героя с идентификатором '10043'. Когда я перехожу (т.е. на маршрут 'heroes/874'), компонент просто визуализирует нового героя. – user2112300

ответ

1

Я думаю, возможная проблема, что heroObservable.merge(tmp) не мутирует heroObservable, но возвращает новые наблюдаемые, которые теряются в вашем коде.

Попробуйте сохранить его в любой переменной и возвращение для getHeroSubscription метода вместо того, чтобы просто return heroObservable

+0

Спасибо, кажется, решает проблему. Есть ли способ мутировать «heroObservable» («положить» один «Наблюдаемый» внутри другого)? – user2112300

+1

Только используя статические методы из Observable, например 'zip' или' forkJoin', вы можете попробовать найти smth в примерах, например https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core /operators/forkjoin.md –

Смежные вопросы