如何正确地观察一个可观察的

时间:2018-05-08 17:42:27

标签: angular rxjs

要从我的组件开始,我声明了observable ......

import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import { tap, map, concat } from 'rxjs/operators';

contactsDataSource$: Observable<any>;

然后我从http服务分配一个流到observable:

this.contactsDataSource$ = this.medialistsrv.getMediaListBuilderData({
    mediaListId: this.mediaListId,
    sortType: this.sortType,
    startRow: this.startRow,
    numRows: this.numRows
}).pipe(
    tap(response => {
        this.mediaList = response
            .filter(items => items.inMediaList === true)
            .map(items => items.contactId);
        this.mediaList.forEach(id => {
            this._contacts.push(this.fb.control(id));
        });
    }),
    map(response => response)
);

并使用异步管道将其引入模板:

<div *ngIf="(contactsDataSource$ | async) as contactList; else loading">

稍后在模板中我介绍了一种加载更多结果的方法。这是我需要连接到初始流

的地方
increment() {
    this.contactsDataSource$.concat(
        this.medialistsrv.getMediaListBuilderData({
            mediaListId: this.mediaListId,
            sortType: this.sortType,
            startRow: (this.numRows + 1),
            numRows: (this.numRows * 2)
        }).map(response => response)
    );
}

运行时我在控制台中收到错误消息:

ng:///MediaListModule/MediaListBuilderComponent.ngfactory.js:351 ERROR TypeError: this.contactsDataSource$.concat is not a function

我仍然在rxjs学习悬崖,显然我不明白如何正确地做到这一点。我在这里缺少什么?

1 个答案:

答案 0 :(得分:3)

您执行该操作的方式存在的问题是,在第一次调用getMediaListBuilderData后,订阅将完成。您需要在第一次订阅之前设置observable以及它如何连接来自多个源的结果。此外,如果您希望管道中的操作与每个结果一起发生,则需要在串联流之后放置。

从您传递初始调用的concatSubject创建一个observable,它将传递给getMediaListBuilderDataincrement()的所有调用的订阅方法。

this.incrementsSubject = new Subject<myType>();
this.contactsDataSource$ = 
    concat(
        this.medialistsrv.getMediaListBuilderData({
            mediaListId: this.mediaListId,
           sortType: this.sortType,
           startRow: this.startRow,
           numRows: this.numRows
        }
        , this.incrementsSubject)
    .pipe(
        tap(response => {
            this.mediaList = response
               .filter(items => items.inMediaList === true)
               .map(items => items.contactId);
            this.mediaList.forEach(id => this._contacts.push(this.fb.control(id)));
        }),
    );

increment() {

    this.medialistsrv
        .getMediaListBuilderData({
            mediaListId: this.mediaListId,
            sortType: this.sortType,
            startRow: (this.numRows + 1),
           numRows: (this.numRows * 2)
         })
         .subscribe(this.incrementsSubject);
}