Некорректная реализация подписки на компонент Angular2

У меня есть общее представление о том, как работают наблюдаемые Angular2 / RXJS, когда они подписаны, но я где-то делаю ошибку.

В моем сервисе у меня есть наблюдаемое, например:

    // Source
    private objectDetailsCache = new Subject<ObectDetails>();
    // Stream
    public objectDetails$ = this.objectDetailsCache.asObservable().cache();

Сервис управляет наблюдаемым с помощью следующих методов:

    updateObject(object: ObjectDetails): Observable<ObjectDetails> {

    let objectMapped = this.mappingService.mapObjectDetailsToObject(object);

    this._HTTPService.update(this._objectUrl + object.id, objectMapped)
        .subscribe(o => {
            this.objectDetailsCache.next(o);
        });
    return this.objectDetails$.last();
    }

    getObjectDetails(id: number): Observable<ObjectDetails> {
    this._HTTPService.get(this._objectUrl + id + '/details')
        .subscribe(o => {
            this.objectDetailsCache.next(o);
        })
    return this.objectDetails$.last();
    }

У меня есть родительский компонент, который подписывается на наблюдаемый и отслеживает изменения, внесенные в него его дочерними элементами.

    constructor(private objectService: ObjectService) {
    objectService.objectDetails$.subscribe(o => this.object = o);
}

Затем компонент сообщает приложению, за каким объектом он хочет наблюдать:

    ngOnInit() {
        this.loadObjectDetails();
    }

    loadObjectDetails() {
        this.sub = this.route.params.subscribe(params => {
            let id = +params['id'];
            this.objectService.getObjectDetails(id)
                .subscribe(
                o => {  },
                error => { });
        });
     }

Пока все в порядке. Проблема возникает, когда дочерние компоненты подписываются на наблюдаемый родительский объект:

    ngOnInit() {
       this.sub = this.objectService.objectDetails$.subscribe(
            o => {
                this.object = o;
                this.getHeaders()
            }
       );
    }

    ngOnDestroy(){
        this.sub.unsubscribe();
    }

Когда родитель изменяет объект, за которым он наблюдает, дочерний элемент получает удар всеми объектами, которые наблюдались ранее, а не только последним. Итак, в случае этого дочернего элемента, если родитель наблюдал 3 объекта, this.getHeaders () вызывается 3 раза, когда дочерний элемент подписывается.

Я пробовал переместить дочерние методы в полную часть подписки:

() => this.getHeaders()

но никогда не попадает.

Я пробовал поместить родительскую подписку в ngOnInit () и отказаться от подписки в ngDestroy (), но он не может подписаться ни на что подобное.

Любые предложения о том, как я могу отрегулировать, как я это делаю, были бы замечательными.

Надеюсь, это имеет смысл, заранее спасибо.


person Mark    schedule 08.12.2016    source источник
comment
Я не уверен, что значение присутствует в конструкторе или ngInit .... Я создал метод GetMyObservable (), который возвращает наблюдаемый объект, и я подписываюсь на этот метод .... работает как очарование. Не знаю, твоя проблема в этом или нет.   -  person John Baird    schedule 08.12.2016
comment
спасибо за совет, Джон, похоже, моя подписка работает, но на самом деле я не хочу подписку. Я думаю, мне нужно что-то, чтобы дать мне снимок наблюдаемого, что-то вроде .last ()   -  person Mark    schedule 09.12.2016


Ответы (1)


Мне удалось обойти проблему с помощью BehviourSubject из библиотеки RXJS:

https://xgrommx.github.io/rx-book/content/subjects/behavior_subject/index.html

в частности, член .getValue () возвращает последний объект в наблюдаемом потоке. Поэтому вместо того, чтобы дочерние компоненты подписывались на наблюдаемое, они просто запрашивают последнее значение. Таким образом, когда они обновляют наблюдаемый пар, они не перерабатывают себя.

person Mark    schedule 15.12.2016