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

0

Я пытаюсь сделать простую связь между угловым компонентом и сервисом, но я не могу понять, как это сделать с помощью 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;}

Где моя ошибка?

  • 1
    Почему вы подписываетесь на параметр маршрута? Я не уверен, что понял вашу цель здесь.
  • 0
    Так как я HeroViewerComponent к маршруту heroes/:id чтобы можно было изменить параметр, не разрушая компонент. Например, я нахожусь на маршруте heroes/10043 и HeroViewerComponent рендеринга героя с идентификатором 10043 . Когда я двигаюсь дальше (т.е. по маршруту heroes/874 ), компонент просто рендерит нового героя.
Теги:
angular
rxjs5

1 ответ

1

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

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

  • 0
    Спасибо, похоже, решил проблему. Есть ли способ heroObservable («поместить» один Observable внутрь другого)?
  • 1
    Только используя статические методы из Observable, такие как zip или forkJoin - вы можете попытаться найти что- forkJoin в примерах, таких как github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/…

Ещё вопросы

Сообщество Overcoder
Наверх
Меню