Я пытаюсь сделать простую связь между угловым компонентом и сервисом, но я не могу понять, как это сделать с помощью Observable.
Мой компонент HeroViewerComponent
подписывается на id
параметра router и передает его службе 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;}
Где моя ошибка?
Я думаю, возможная проблема, что heroObservable.merge(tmp)
не мутирует heroObservable
, но возвращает новые наблюдаемые, которые теряются в вашем коде.
Попробуйте сохранить его в любой переменной и вернуть метод getHeroSubscription
а не просто return heroObservable
heroObservable
(«поместить» один Observable
внутрь другого)?
zip
или forkJoin
- вы можете попытаться найти что- forkJoin
в примерах, таких как github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/…
HeroViewerComponent
к маршрутуheroes/:id
чтобы можно было изменить параметр, не разрушая компонент. Например, я нахожусь на маршрутеheroes/10043
иHeroViewerComponent
рендеринга героя с идентификатором10043
. Когда я двигаюсь дальше (т.е. по маршрутуheroes/874
), компонент просто рендерит нового героя.