可观察到的管道shareReplay与ReplaySubject.observableOf

时间:2018-08-19 19:12:19

标签: angular rxjs6

shareReplay无法正常运行。从文档中,我希望以下代码是等效的。

@Injectable( {
    providedIn: 'root'
} )
export class CartService {

    private list: InventoryItem[] = [];
    cart: Observable<ReadonlyArray<Readonly<InventoryItem>>> = of( this.list ).pipe(
        shareReplay( 1 )
    );

    constructor() {}

    addItem( item: InventoryItem ) {
        this.list.push( item );
    }
}

@Injectable( {
    providedIn: 'root'
} )
export class CartService {

    private list: InventoryItem[] = [];
    private subject = new ReplaySubject<ReadonlyArray<Readonly<InventoryItem>>>(1);
    cart: Observable<ReadonlyArray<Readonly<InventoryItem>>> = this.subject.asObservable();

    constructor() {}

    addItem( item: InventoryItem ) {
        this.list.push( item );
        this.subject.next(this.list);
    }
}

但只有第二个版本可以工作,其中所有用户都在调用addItem(...)时收到事件。

第一个示例仅在我的根组件中的一个实例中起作用,而在使用相似语法的任何其他组件中均不起作用。

[matBadge]="(cartService.cart | async)?.length"

我已经验证了仅创建了服务的一个实例,任何人都可以让我对第一段代码中发生的事情有一些了解吗?

1 个答案:

答案 0 :(得分:1)

您的示例不一样。

private list: InventoryItem[] = [];
    cart: Observable<ReadonlyArray<Readonly<InventoryItem>>> = of( this.list ).pipe(
        shareReplay( 1 )
    );

of(this.list)将采用最新 this.list,并且在您订阅时会获得列表,但如果您进行this.list.push(...),则不会再次获得列表。您将不得不再次订阅。

另一方面,当您使用“主题”在列表中发出更改信号时,您的订户将再次收到通知。

所以这很关键:

this.subject.next(this.list);