【问题标题】:AsyncSubject - How to get data only one time?AsyncSubject - 如何只获取一次数据?
【发布时间】:2017-10-30 09:42:09
【问题描述】:

在 Angular4 中使用 Rxjs 的问题

RxJS 版本: 5.5.0

重现代码: 服务 subject= new AsyncSubject<String>(); subject.next(data); subject.complete();

组件 ngOnInit(){ subject.subscribe(); }

预期行为: 只接收一次数据,然后清理主题中的数据,不再接收或强制取消订阅主题。

实际行为: 在服务中,我有 asyncSubject 发出一些数据。在某些组件中,我订阅了我的 asyncSubject,数据来自每个组件初始化。我尝试取消订阅主题,但在下一次组件初始化后它再次订阅。

附加信息: 角度版本 4.4.6 Chrome 版本 61

仪表板组件

constructor(private userEvents: UserEvents,) {}

ngOnInit() {
    this.successLogged();
}


successLogged() {
    this.userEvents.successLoggedObservable.subscribe(message => {
        console.log("WORK");
    });
}

用户事件

private  successLoggedObservable = new AsyncSubject<String>();
get successLogged() {
    return this.successLoggedObservable;
}

登录组件

this.userEvents.successLoggedObservable.next("MESSAGE");
this.userEvents.successLogged.complete();
this.stateService.go('dashboard');

【问题讨论】:

  • 所以让我说对了,你想触发一个事件,然后从登录导航到仪表板并在那里接收一个事件?您要么必须使用AsyncReplay 主题并修复您的用例,要么使用其他形式的组件通信,例如router params。你这里的逻辑没有意义。
  • 在我登录 LoginComponent 后,我想将登录成功消息传递给 DashboardComponent。你知道我怎样才能达到它吗?
  • 正如我所说,如果您使用路由器导航到仪表板组件,您可以使用路由器参数向它发送数据。
  • 我使用路由参数解决它。谢谢!

标签: javascript angular rxjs observable


【解决方案1】:

这是AsyncSubjectngOnInit() 的正常行为。每当您订阅 AsyncSubject 时,它都会发出最后一个发出的值,因此每次您的组件初始化时,它都会收到最后发出的值。如果您想避免这种情况,请改用常规的Subject(或PublishSubject

来自官方文档的信息:ReactiveX Subject

【讨论】:

  • 主题不起作用。当我转到我的组件 A 时,我订阅了 Subject Observable,然后转到组件 B,在那里我调用 next 方法并返回 A 一切正常(调用订阅者)。但是当我第一次去组件 B 和下一个 A 时,订阅者不起作用。
  • 你不能指望我在没有看到你的代码的情况下帮助你。
【解决方案2】:

在组件中尝试ReplaySubject(1)publish()connect()

// Service
const source = new Rx.ReplaySubject(1).publish()
source.next(1)
// source.complete() - not needed


// Simulate first subscribing component 
const sub1 = source.subscribe(x => console.log('sub1', x))
source.connect()

// onDestroy
sub1.unsubscribe()


// Now resubscribe
const sub2 = source.subscribe(x => console.log('sub2', x))
source.connect()
// No value emitted

工作示例:CodePen

基本上,publish()connect() 使 observable 变得很热,因此新订阅在订阅点接收流。

不适用于 AsyncSubject,但我还没有弄清楚原因。

【讨论】:

    【解决方案3】:

    这是在每次加载时调用 ngOnInit 的常见行为。您可以创建 bool 变量,如果它已经加载,则分配 false 值;

    subscribed: Boolean = false;
    
    ngOnInit() {
      if (!subscribed) {
        subject.subscribe();
        this.subscribed = true;
      }
    }
    

    【讨论】:

    • 它不起作用。我每次加载组件时 subscribed 都有 false 值并且订阅者被调用。
    猜你喜欢
    • 2021-12-22
    • 2021-01-04
    • 2021-12-22
    • 2022-01-23
    • 1970-01-01
    • 2017-03-09
    • 2020-05-08
    • 2017-06-09
    • 2020-09-10
    相关资源
    最近更新 更多