Angular BehaviorSubject.next()未发出更新的值
我只是想为我对RxJS和可观测数据缺乏理解而道歉。我之前发布了一个问题,但措辞非常糟糕,我知道这是不可理解的,所以一天后我想我可以更好地解释我的问题Angular BehaviorSubject.next()未发出更新的值,angular,typescript,rxjs,rxjs6,rxjs-observables,Angular,Typescript,Rxjs,Rxjs6,Rxjs Observables,我只是想为我对RxJS和可观测数据缺乏理解而道歉。我之前发布了一个问题,但措辞非常糟糕,我知道这是不可理解的,所以一天后我想我可以更好地解释我的问题 我的代码的目标是获取用户输入,将其作为操作流传递给我的数据流,将输入与我的间隔数组进行比较,如果存在,则返回单个间隔。如果它不存在(这是我正在努力的地方)返回一个可观察到的,我可以在我的bay.page.ts中调用它,并检查它的是否为true或false。如果为假[显示客户端错误]。 如果是true,则向前导航到结果页面 Mybay service
bay.page.ts
中调用它,并检查它的是否为true
或false
。如果为假[显示客户端错误]。
如果是true
,则向前导航到结果页面bay service.ts
类包含我的数据和操作流:为什么观察对象的值没有更新?求你了,我的心很痛,我不知道还能做什么。如果没有观察者订阅,一个可观察者什么也不做。您没有订阅
selectedBay$
observable。因此,来自combinelateest
的管道中的代码根本不会执行,不管新值被发送到动作流多少次,并且您总是从invalidBay
接收初始false
值
一些建议:
BehaviorSubject
是一个可观察的多播对象,您应该始终保持它的私有性,以最小化对它调用next()
的范围。使用.asObservable()
方法将其公开为可观察,如果任何外部代码需要发出新值的能力,请提供一个公共方法。您已经以这种方式处理了baySelectedSubject
。考虑对<代码> SimuldBuy.P/>进行同样的操作。
onSubmit()
中删除订阅并将其放入ngOnInit()
订阅
引用。您只需按以下方式订阅-
this.bayService.invalidBay$.subscribe(值=>。。。
而不是-
this.subscription=this.bayService.invalidBay.subscription(值=>。。。
如果确实需要Subscription
引用,请记住在ngondstroy
方法中进行清理-
ngondestory():void{
this.subscription.unsubscripte();
}
这将在组件被销毁后立即取消对可观察对象的订阅。否则,订阅
引用将保留可观察对象,即使在组件被销毁后,这将最终导致内存泄漏
根据建议(相对)更好地实施:
服务-
导出类BayServiceService{
私有baysUrl=‘api/bays’;
bays$=this.http.get(this.baysUrl)
.烟斗(
点击(data=>console.log('Bays:',JSON.stringify(data)),
catchError(this.handleError)
);
private baySelectedSubject=新行为主体(0);
baySelectedAction$=this.baySelectedSubject.asObservable();
private invalidBay=新行为主体(false);
invalidBay$=this.invalidBay.asObservable();
selectedBay$=CombineTest([this.bays$,this.baySelectedAction$]))
.烟斗(
地图(([bays,selectedBayNumber])=>{
让bay=bays.find(p=>p.bayCode===selectedBayNumber);
如果(!间隔){
this.invaliday.next(false);
}否则{
this.invaliday.next(true);
返回湾;
}
}));
selectedBayChanged(selectedBayNumber:number):无效{
this.baySelectedSubject.next(selectedBayNumber);
}
}
在您的组件中-
ngOnInit():void{
此.bayService.selectedBay$.subscribe(
p=>{
//用间隔值做点什么
}
);
此.bayService.invaliday$.subscribe(
p=>{
//用invalidBay值做一些事情
}
);
}
onSubmit():void{
this.bayService.selectedBayChanged(this.bayForm.get('bayStart').value);
}
ngOnDestroy():void{
//如果您存储了订阅引用
this.subscription.unsubscripte();
}
Wow,我真的很感谢这些建议,我同意他们!但是,我不想在我的ngOnInit中使用this.bayService.invalidBay$.subscribe
,因为每次运行这段代码时都应该更新它:this.bayService.selectedBayChanged(this.baysform.get('bayStart').value)
这将在用户提交时发生。这段代码将触发selectedBay$,并根据用户的输入触发invalidBay$observable以发出一个值。但事实并非如此,它只是false。我想处理该observable的值,如果为false,则抛出客户端错误,或者向前移动。@Donnygroezinger需要从invalidBay$
更新的值,而不是新订阅。将订阅代码放入ngOnInit
中,您仍将在任何时候收到更新的发射。下一步()在服务中的invalidBay
上被调用。这就是可观察对象的工作方式。测试我在答案中实现的版本,你就会明白。我做了,我正在尝试听你说。我不想要this.bayService.selectedBay$.subscribe()
在这个文件上,因为我已经在我的结果页面中声明了它,它将返回一个选定的间隔。我只希望this.bayService.invalidBay$
结果发出一个false或true。并在submit上处理它。
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);
}