BehaviorSubject无关紧要的行为

时间:2018-06-14 12:13:17

标签: angular angular6 behaviorsubject rxjs6

在我的Angular 6项目中,我有3个组件,登录,注册和主页。

enter image description here

当用户在应用程序中成功注册时,我想在绿色区域内显示此“注册成功”消息。为此,我在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()也会返回false,这也是预期的结果。但是在成功注册和登录后(重定向到主组件),如果我立即注销,我仍然可以获得getSuccessMessage()的真正价值。是假设发生了吗?或者我在这里遗漏了什么?

修改
还有其他/更好的方法,我可以做这个操作,有或没有行为主题?

2 个答案:

答案 0 :(得分:1)

Angular服务是单例(默认情况下)。此外,当您调用array = [:foo, :bar, :mnky] def content_for_key key return :baz if key == :foo return :qux if key == :bar end array.zip(array.map(&method(:content_for_key))).to_h #=> {:foo=>:baz, :bar=>:qux, :mnky => nil} # or [array,array.map(&method(:content_for_key))].transpose.to_h #=> {:foo=>:baz, :bar=>:qux, :mnky=>nil} 以路由到另一个页面时,某些组件将被销毁,但服务不会。只要您停留在您的站点路线中,每次导航时重新加载整个应用程序是没有意义的。

这有时会让人感到惊讶,因为网址会发生变化。但是,URL更改不需要重新加载页面。

但是,当您刷新页面或导航到外部页面并返回时(就像您在openid connect工作流中一样),则会重新加载整个应用程序。

无论如何,如果你正在寻找一个更好的方法,那么只需立即发送true然后将false发送到你的行为主题中。您的组件将获得两个值但在false时不执行任何操作。然后,当你导航时,组件将被销毁(服务是单件,但组件不是),并重新创建,当新组件读取时,它将读为false。

您也可以使用普通的Subject而不是BehaviorSubject。

答案 1 :(得分:0)

加载登录页面时,执行订阅方法。这将显示消息'注册成功',因为标志始终为真。

  ngOnInit() {
    this.successMessageSubscriber = this._sharedService.getSuccessMessage().subscribe((flag) => {
        if (flag) {
            this.message="successfully registered";
        }
    });
  }

解决方案是在服务中添加另一个方法来清除标志。

clearMessage(): void {
  this.isRegistrationSuccessfully.next(false);
}

然后在取消订阅之前调用此方法。

  ngOnDestroy() {
      if (this.successMessageSubscriber) {
        this._sharedService.clearMessage();
        this.successMessageSubscriber.unsubscribe();
      }
  }

加载登录后,邮件已订阅。当登录被卸载时,该消息被取消订阅。该标志未提前清除。代码中的这一更改将重置标志。