angular - BehaviorSubject .next() 没有发出更新的值
我只是想为我对 RxJS 和 Observables 的理解不足道歉。我之前发过一个问题,但表述得很糟糕,我知道别人无法理解,所以过了一天后,我想我可以更好地解释我的问题。
- 我的代码目标是获取用户输入,将其作为动作流传递到我的数据流,比对输入与我的泊位数组,如果存在,则返回该单个泊位。如果不存在 (这是我正在挣扎的部分),则返回一个可观察对象,我可以在
bay.page.ts中回调,并检查它是否为true或false。如果是false[显示客户端错误]。如果是true,则导航到结果页面。 - 我的
bay-service.ts类包含我的数据和操作流:
export class BayServiceService {
private baysUrl = 'api/bays';
bays$ = this.http.get<Bay[]>(this.baysUrl)
.pipe(
tap(data => console.log('Bays: ', JSON.stringify(data))),
catchError(this.handleError)
);
/*--------------------------------------------------------------*/
// Grab A Single Bay
private baySelectedSubject = new BehaviorSubject<number>(0);
baySelectedAction$ = this.baySelectedSubject.asObservable();
invalidBay = new BehaviorSubject<boolean>(false);
selectedBay$ = combineLatest([
this.bays$,
this.baySelectedAction$
])
.pipe(
map(([bays, selectedBayNumber]) => {
if (!bays.find(bay => bay.bayCode === selectedBayNumber)){
this.invalidBay.next(false);
} else {
this.invalidBay.next(true);
return bays.find(bay => bay.bayCode === selectedBayNumber);
}
}),
);
selectedBayChanged(selectedBayNumber: number): void {
this.baySelectedSubject.next(selectedBayNumber);
}
^在上面的代码中,我使用了声明式的 RxJS 方法 selectedBay$,在其中我将我的 bay$ 数据流和 baySelectedAction$ 操作流(包含用户输入)结合起来。然后我对它们进行映射,并将用户输入的 selectedBayNumber 与单个泊位编号进行比较。
问题:我正在尝试使用 Observable -> invalidBay=new BehaviorSubject<boolean>(false);,这是我在 bay-service.ts 中创建的,并检查它的结果:如果为 true,则向前导航。如果为 false,则显示客户端错误提示,说明它不存在。然而,如果用户输入一个有效的泊位号,我尝试通过 this.invalidBay.next(true); 将该 Observable 改为 true,但是,observable 的值不会更新?BehaviorObservable 保持其默认值 'false'。所以代码部分有效,但不完全。
- 这是我在
bay-page.ts中的onSubmit方法,我在这里处理用户输入以进行我的操作流。我将用户输入传递给一个方法(该方法在我的bay-service.ts类中)。根据他们的输入,我尝试订阅那个“应该被更新”的 Observable,然后再从那里继续。但这个 Observable 并没有被更新。请帮忙。
onSubmit() {
this.bayService.selectedBayChanged(this.bayForm.get('bayStart').value);
this.subscription = this.bayService.invalidBay.subscribe(value => {
if (value) {
this.navCtrl.navigateForward([`/results/`]);
} else {
this.bayDoesNotExistError = true;
this.selectedBay = this.bayForm.get('bayStart').value;
this.vibration.vibrate(500);
console.log('Vibrating for 3 second...')
}
})
}
为什么 Observable 的值没有更新?请帮帮我,我脑袋疼,不知道还能做些什么。
答案#1
如果没有观察者订阅,observable 什么也不会做。你没有订阅 selectedBay$ observable。因此,从 combineLatest 开始的 pipe 中的代码根本不会执行,无论向你的 action 流发射多少新值,你总是会收到 invalidBay 的初始 false 值。
一些建议:
BehaviorSubject是一个多播的可观察对象,你应该始终将其保持为私有,以最小化对它调用next()的范围。使用.asObservable()方法将其作为可观察对象暴露,如果任何外部代码需要发出新值的能力,可以提供一个公共方法来实现这一点。你已经以这种方式处理baySelectedSubject。考虑对invalidBay做同样的处理。永远不要将你的订阅代码放在会被执行多次的方法中。每次方法执行时,你都会创建一个新的订阅。Observable 会向每个订阅发出值。因此,请将你的订阅从
onSubmit()中移除,并放到ngOnInit()中。
为您服务,更改 -
invalidBay = new BehaviorSubject<boolean>(false);
到
private invalidBay = new BehaviorSubject<boolean>(false);
invalidBay$ = this.invalidBay.asObservable();
在你的组件中 -
ngOnInit(): void {
this.bayService.selectedBay$.subscribe(
p => {
// do something with the Bay value
}
);
this.bayService.invalidBay$.subscribe(
p => {
// do something with the invalidBay value
}
);
}
onSubmit(): void {
this.bayService.selectedBayChanged(this.bayForm.get('bayStart').value);
}
