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();
      }
  }

加载登录时,已订阅消息。当登录被卸载时,消息被取消订阅。该标志未提前清除。此代码更改将重置标志。