BehaviorSubject 无所谓的行为
BehaviorSubject indifferent behavior
在我的 Angular 6 项目中,我有 3 个组件,登录、注册和主页。
当用户在应用程序中成功注册时,我想在绿色区域内显示此 "Registration successful" 消息。为此,我在 shared.service.ts
中创建了一个 BehaviorSubject
private isRegistrationSuccessfully: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
/* Successful registration */
getSuccessMessage(): Observable<boolean> {
return this.isRegistrationSuccessfully.asObservable();
}
setSuccessMessage(value: boolean): void {
this.isRegistrationSuccessfully.next(value);
}
在register.component.ts文件中成功注册我正在调用set方法,
onSubmitRegistrationForm() {
// some code
this._sharedService.setSuccessMessage(true);
this._router.navigate(['/' + RouteConstants.LOGIN]);
}
在 login.component.ts 文件中我调用了 getSuccessMessage()
方法,
successMessageSubscriber: any;
ngOnInit() {
this.successMessageSubscriber = this._sharedService.getSuccessMessage().subscribe((flag) => {
if (flag) {
// code for showing div
}
});
}
ngOnDestroy() {
if (this.successMessageSubscriber) {
this.successMessageSubscriber.unsubscribe();
}
}
根据此代码,在成功注册后我得到了预期的结果,如果我刷新页面然后 getSuccessMessage()
returns false,这又是预期的结果。但是在成功注册和登录(重定向到主页组件)之后,如果我立即注销,我仍然会得到 getSuccessMessage()
的真实值。它应该发生了吗?还是我遗漏了什么?
编辑
还有什么 other/better 方法可以让我做这个操作,有或没有 Behavior Subject?
Angular 服务是单例的(默认情况下)。此外,当您调用 router.navigate
路由到另一个页面时,一些组件将被销毁,但服务不会。只要您停留在站点路线内,就没有必要在每次导航时重新加载整个应用程序。
这有时会让人们感到惊讶,因为 URL 发生了变化。但是,URL 更改不需要重新加载页面。
但是,当您刷新页面或导航到外部页面并返回时(就像您可能在 openid 连接工作流中一样),您的整个应用程序都会重新加载。
无论如何,如果您正在寻找更好的方法,请立即将 true 和 false 发送到您的行为主题中。您的组件将获得这两个值,但对 false 不执行任何操作。然后,当您导航时,该组件将被销毁(服务是单例但组件不是)并重新创建,当新组件读取时它将读取 false。
您也可以只使用普通的 Subject 而不是 BehaviorSubject。
加载登录页面时,执行订阅方法。这将显示消息 'registration successful',因为标志始终为真。
ngOnInit() {
this.successMessageSubscriber = this._sharedService.getSuccessMessage().subscribe((flag) => {
if (flag) {
this.message="successfully registered";
}
});
}
解决办法是在服务中再增加一个清除flag的方法
clearMessage(): void {
this.isRegistrationSuccessfully.next(false);
}
然后在取消订阅前调用此方法。
ngOnDestroy() {
if (this.successMessageSubscriber) {
this._sharedService.clearMessage();
this.successMessageSubscriber.unsubscribe();
}
}
加载登录时,已订阅消息。当登录被卸载时,消息被取消订阅。该标志未提前清除。此代码更改将重置标志。
在我的 Angular 6 项目中,我有 3 个组件,登录、注册和主页。
当用户在应用程序中成功注册时,我想在绿色区域内显示此 "Registration successful" 消息。为此,我在 shared.service.ts
中创建了一个 BehaviorSubjectprivate isRegistrationSuccessfully: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
/* Successful registration */
getSuccessMessage(): Observable<boolean> {
return this.isRegistrationSuccessfully.asObservable();
}
setSuccessMessage(value: boolean): void {
this.isRegistrationSuccessfully.next(value);
}
在register.component.ts文件中成功注册我正在调用set方法,
onSubmitRegistrationForm() {
// some code
this._sharedService.setSuccessMessage(true);
this._router.navigate(['/' + RouteConstants.LOGIN]);
}
在 login.component.ts 文件中我调用了 getSuccessMessage()
方法,
successMessageSubscriber: any;
ngOnInit() {
this.successMessageSubscriber = this._sharedService.getSuccessMessage().subscribe((flag) => {
if (flag) {
// code for showing div
}
});
}
ngOnDestroy() {
if (this.successMessageSubscriber) {
this.successMessageSubscriber.unsubscribe();
}
}
根据此代码,在成功注册后我得到了预期的结果,如果我刷新页面然后 getSuccessMessage()
returns false,这又是预期的结果。但是在成功注册和登录(重定向到主页组件)之后,如果我立即注销,我仍然会得到 getSuccessMessage()
的真实值。它应该发生了吗?还是我遗漏了什么?
编辑
还有什么 other/better 方法可以让我做这个操作,有或没有 Behavior Subject?
Angular 服务是单例的(默认情况下)。此外,当您调用 router.navigate
路由到另一个页面时,一些组件将被销毁,但服务不会。只要您停留在站点路线内,就没有必要在每次导航时重新加载整个应用程序。
这有时会让人们感到惊讶,因为 URL 发生了变化。但是,URL 更改不需要重新加载页面。
但是,当您刷新页面或导航到外部页面并返回时(就像您可能在 openid 连接工作流中一样),您的整个应用程序都会重新加载。
无论如何,如果您正在寻找更好的方法,请立即将 true 和 false 发送到您的行为主题中。您的组件将获得这两个值,但对 false 不执行任何操作。然后,当您导航时,该组件将被销毁(服务是单例但组件不是)并重新创建,当新组件读取时它将读取 false。
您也可以只使用普通的 Subject 而不是 BehaviorSubject。
加载登录页面时,执行订阅方法。这将显示消息 'registration successful',因为标志始终为真。
ngOnInit() {
this.successMessageSubscriber = this._sharedService.getSuccessMessage().subscribe((flag) => {
if (flag) {
this.message="successfully registered";
}
});
}
解决办法是在服务中再增加一个清除flag的方法
clearMessage(): void {
this.isRegistrationSuccessfully.next(false);
}
然后在取消订阅前调用此方法。
ngOnDestroy() {
if (this.successMessageSubscriber) {
this._sharedService.clearMessage();
this.successMessageSubscriber.unsubscribe();
}
}
加载登录时,已订阅消息。当登录被卸载时,消息被取消订阅。该标志未提前清除。此代码更改将重置标志。