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

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

问题描述

我有一个公开 asObservable 的商店.一个视图订阅它并显示数据.自从我将其更改为单例服务以来,它一直在首次加载,当我第一次进入该页面时,没有显示任何数据,也没有触发订阅事件.在我对数据执行一些操作后,导致被称为 subject.next 的它更新,视图更新,一切都很好.

我已确保这不是竞争条件问题,并且在调用页面的构造函数时数据在存储中.

事件顺序如下(调试时确认):

  1. 从服务器加载数据
  2. 使用正确的数据调用subject.next()
  3. 调用订阅观察者的组件构造函数

没有订阅事件触发并且没有数据填充,即使它存在于商店中.如果我随后对列表执行某种 crud 操作,一切都会按预期进行级联,则调用 next() 并发生订阅事件.

如何让页面在页面加载时读取数据?

<块引用>

数据存储

protected _subject$: Subject>;this._subject$.next(newData);//通过控制台确认这在数据良好的情况下发生getcontacts$():Observable{返回 this._subject$.asObservable();}

<块引用>

component - 我已经尝试将下面的块放在构造函数和 ngAfterViewInit 中,结果相同

//上面的数据已经设置好之后this.contacts$.subscribe(data => {//该块在页面加载时不执行});

解决方案

事件顺序如下(调试时确认):

  1. 从服务器加载数据
  2. 使用正确的数据调用subject.next()
  3. 调用订阅观察者的组件构造函数

这是因为vanilla Subject 不缓冲任何东西.当一条消息发出时,如果在那个确切的时间没有人订阅,那么这条消息就永远消失了,没有人会收到它.

如果你想保持最后一条消息被缓冲(对于所有订阅者),那么你可以使用 BehaviorSubjectReplaySubject

import { BehaviorSubject } from 'rxjs/BehaviorSubject';从 'rxjs/ReplaySubject' 导入 { ReplaySubject };sub1 = new BahaviorSubject(null);sub2 = 新的 ReplaySubject(1);

从语义上讲,BehaviorSubject 表示一个随时间变化的值,您可以使用初始值对其进行初始化.它将保持最后一项始终缓冲,直到下一项将其推出.

ReplaySubject 的语义是缓冲发出的项目数量,达到缓冲区大小,并在订阅时将它们全部发送给订阅者.我们可以使用缓冲区大小初始化 ReplaySubject.缓冲区大小为 1,将使它的行为与 BehaviorSubject 一样(但我们不需要用值对其进行初始化).

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. Data is loaded from server
  2. subject.next() is called with correct data
  3. component constructor is called which subscribes to observer

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

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();
}

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. Data is loaded from server
  2. subject.next() is called with correct data
  3. component constructor is called which subscribes to observer

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.

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);

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.

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).

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

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