我有一个Angular服务,其布尔属性为 must_checkout 。我的服务还包含一个名为 observable_must_checkout 的属性,该属性是查看 must_checkout 的BehaviorSubject。
然后,在我的组件中,我订阅 observable_must_checkout 。
这有效,并且组件在第一次 must_checkout 更改时会收到事件。但是,这只会触发一次,并且随后对 must_checkout 所做的更改不起作用:
服务:
import { Injectable, Input, Output } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
export class OrderingService
{
must_checkout: boolean;
observable_must_checkout = new BehaviorSubject<boolean>(this.must_checkout);
constructor([...])
{
this.observable_must_checkout = new BehaviorSubject<boolean>(this.must_checkout);
}
ChangeSomething()
{
console.log("changing the value here...");
this.must_checkout = true;
}
}
父组件:
import { Component, OnInit } from '@angular/core';
import { OrderingService } from 'src/app/services/ordering.service';
@Component({
selector: 'app-settle',
templateUrl: './settle.component.html',
styleUrls: ['./settle.component.css']
})
export class SettleComponent implements OnInit
{
constructor(private OrderingService: OrderingService) { }
ngOnInit()
{
this.basket = new OrderingService();
this.basket.observable_must_checkout.subscribe((newValue: boolean) => { alert("value changed: " + newValue) });
}
ngOnDestroy() {
this.basket.observable_must_checkout.unsubscribe();
}
}
答案 0 :(得分:3)
我没有看到对next()的调用,这是您将新事件激发到BehaviorSubject的当前订阅者的方式。您正在寻找这样的东西。
ChangeSomething()
{
console.log("changing the value here...");
this.observable_must_checkout.next(true);
}
https://www.learnrxjs.io/subjects/
此外,您无需在构造函数中初始化主题,因为您在上面的几行中做了此操作:
observable_must_checkout = new BehaviorSubject<boolean>(this.must_checkout);
constructor([...])
{}
答案 1 :(得分:2)
您快到了。创建BehaviorSubject时,它将使用值must_checkout
作为其初始值,然后将其丢弃。这意味着对must_checkout
所做的任何更改都会对您的可观察物产生零影响。这等于您在做什么。在此处复制并粘贴此代码,以查看mustCheckOut
中的更改如何不发出新信号。
https://stackblitz.com/edit/rxjs-4jynuj?devtoolsheight=60
import { of, BehaviorSubject } from 'rxjs';
import { map } from 'rxjs/operators';
let mustCheckOut:boolean = false;
let obsMustCheckOut: BehaviorSubject<boolean> = new BehaviorSubject(mustCheckOut);
obsMustCheckOut.asObservable().subscribe(signal => {
console.log("I got a signal!", signal)
})
// This does not work.
// Even though you change the source `mustCheckout`, the BehaviorSubject does not listen to the change in this variable. You must ping a subject which can emit a signal to any subscribers.
setTimeout(() => {
mustCheckOut = true
}, 100)
听起来好像您想在must_checkout
每次更改时发出一个新信号。您需要将must_checkout
变量转换为可以发出信号的变量!然后,订阅的所有内容都会受到影响。
import { of, BehaviorSubject,Subject, Observable } from 'rxjs';
import { map, tap } from 'rxjs/operators';
let mustCheckOut: Subject<boolean> = new Subject();
let obsMustCheckOut: Observable<boolean> = mustCheckOut.asObservable().pipe(
tap((signal) => console.log('I got the signal', signal)),
// other manipulation or async requests can occur here.
)
obsMustCheckOut.subscribe(signal => {
console.log("Here is the current signal!!!", signal)
})
setTimeout(() => {
mustCheckOut.next(true)
}, 100)
setTimeout(() => {
mustCheckOut.next(false)
}, 2600)
setTimeout(() => {
mustCheckOut.next(true)
}, 5500)
希望这对您有所帮助。让我知道是否需要进一步说明。可以在这里找到更多的阅读内容:https://www.learnrxjs.io/subjects/behaviorsubject.html
答案 2 :(得分:0)
我有同样的问题,但原因不同。
这是我的声明。
private clients: BehaviorSubject<ClientSummary[]> = new BehaviorSubject(undefined);
public clients$: Observable<ClientSummary[]> = this.clients.asObservable();
以及它的消费方式
this.clientService.clients$.subscribe(clients => {
// do something with clients
console.log(clients);
});
页面加载后,可观察对象触发了以下日志
undefined
但是,在BehaviorSubject
上调用next时,可观察对象不再触发。
this.clients.next([/* some clients*/]);
您能看到问题吗?
这很微妙,花了我一段时间才能找到答案。
解决方案
更新初始值!
private clients: BehaviorSubject<ClientSummary[]> = new BehaviorSubject([]);
我不知道为什么,但是通过此更改,每次在BehaviorSubject
上调用下一次时,可观察到的不更新。
至于为什么我首先在那里没有定义? 大概复制并粘贴!