观察者订阅不会在第一次加载到Component时触发 [英] Observer subscribe not firing on first load to Component

查看:86
本文介绍了观察者订阅不会在第一次加载到Component时触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个暴露asObservable的商店。视图订阅此并显示数据。因为我已将其更改为Singleton服务,所以它正在进行首次加载,当我第一次进入页面时,没有显示数据且没有触发订阅事件。在对数据执行某些操作之后,会导致subject.next被调用,它会更新并且视图会更新,而且一切都很棒。

I have a store which exposes an asObservable. A view subscribes to this and displays the data. It was working on first load since I've changed it to a Singleton service, when I first go to the page no data is displayed and no subscribe event triggered. After I perform some operation on the data which causes the subject.next to be called it updates and the view updates and everything is great.

我确保这不是一个竞争条件问题,并且在调用页面构造函数时数据存储在商店中。

I've ensured this is not a race condition problem and that the data is in the store at the time the page's constructor is called.

事件序列如下(在调试期间确认):

Sequence of events is as follows (confirmed during debugging):


  1. 数据从服务器加载

  2. 用正确的数据调用subject.next()

  3. 调用组件构造函数订阅观察者

没有订阅事件触发且没有数据填充,即使它存在于商店里。如果我然后在列表上执行某种crud操作,则所有内容都按预期级联,调用next(),并发生订阅事件。

No subscribe event fires and no data populates, even though it exists in the store. If I then perform some kind of crud operation on the list everything cascades through as expected, next() is called, and a subscribe event occurs.

我如何获得在页面加载时读取数据的页面?

How can I get the page to read data on page load?


data.store

data.store



protected _subject$: Subject<Array<any>>;
this._subject$.next(newData);  // confirmed via console this happens with good data

get contacts$(): Observable<any> {
  return this._subject$.asObservable();
}




组件 - 我试过把两者放在一起在构造函数和ngAfterViewInit中的块下面,结果相同

component - I've tried both putting the below block in the constructor and in ngAfterViewInit, same result



// this happens after the above data is already set
this.contacts$.subscribe(data => {
    // this block does not execute on page load
  });


推荐答案


事件顺序是如下(在调试期间确认):

Sequence of events is as follows (confirmed during debugging):


  1. 从服务器加载数据

  2. subject.next(用正确的数据调用

  3. 调用组件构造函数订阅观察者


这是因为vanilla Subject 没有缓冲任何东西。发出消息时,如果没有人在该确切时间订阅,则消息将永远消失,没有人会收到消息。

It's because the vanilla Subject doesn't buffer anything. When a message is emitted, if there is no one subscribed at that exact time, then the message is gone forever and no one will receive it.

如果你想保留最后一条消息(对于所有订阅者),那么你可以使用 BehaviorSubject ReplaySubject

If you want to keep the last message buffered (for all subscribers), then you can use the BehaviorSubject or the ReplaySubject

import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { ReplaySubject } from 'rxjs/ReplaySubject';

sub1 = new BahaviorSubject<any>(null);
sub2 = new ReplaySubject<any>(1);

从语义上讲, BehaviorSubject 表示一个值随时间变化,并使用初始值初始化它。它将保持最后一项始终缓冲,直到下一项推出它。

Semantically, the BehaviorSubject represents a value that changes over time, and you initialize it with the initial value. It will keep the last item always buffered until the next item pushes it out.

ReplaySubject 的语义是缓冲发出的项目数量,最大缓冲区大小,并在订阅时将它们全部发送给订阅者。我们可以使用缓冲区大小初始化 ReplaySubject 。缓冲区大小为1,将使其行为类似于 BehaviorSubject (但我们不需要使用值初始化它)。

The Semantics of the ReplaySubject is to buffer the number of items emitted, up to the buffer size, and send them all to subscribers when subscribed to. We can initialize the ReplaySubject with a buffer size. A buffer size of 1, will make it behave just like a BehaviorSubject (but we don't need to initialize it with a value).

这篇关于观察者订阅不会在第一次加载到Component时触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆