【问题标题】:How do I subscribe a global variable to a BehaviorSubject?如何将全局变量订阅到 BehaviorSubject?
【发布时间】:2018-06-30 14:33:03
【问题描述】:

我正在构建一个登录功能,我希望 app.component 模板中的某些按钮在用户登录的那一刻出现。我正在尝试为此使用 BehaviorSubject。我为模板中的按钮使用*ngIf,条件是一个名为loggedIn 的变量。但是,当我尝试使用 SubjectBehavior 订阅的结果初始化 loggedIn 变量时,我得到了错误:

ERROR in app.component.ts(10,3): error TS2322: Type 'Observable<boolean>' is not assignable to type 'boolean'. 

我不知道是什么原因造成的,因为我返回的是布尔值,而不是可观察值。这是app.component的代码:

export class AppComponent {
  private loggedIn: boolean = this.loginService.isLoggedIn().pipe(
    map((isLoggedIn: boolean) => {         // {3}
      if (!isLoggedIn){
        return false;
      }
      return true;
    }));

  constructor(private loginService: LoginService){}

  logout():void{
    this.loginService.logout();
  }

}

这里是loginService的相关代码:

   isLoggedIn():BehaviorSubject<boolean>{
    return this.loggedIn; 
  }

  login(username: string, password: string): Observable<boolean> {
    return this.http.post(this.authUrl, JSON.stringify({username: username, password: password}), {headers: this.headers}).map((response: Response) => {
            // login successful if there's a jwt token in the response
            let token: any = response.json().token;
            if (token) {
                // store username and jwt token in local storage to keep user logged in between page refreshes
                localStorage.setItem('currentUser', JSON.stringify({ username: username, token: token }));
                this.loggedIn.next(true);
                // return true to indicate successful login
                return true;
            } else {
                // return false to indicate failed login
                return false;
            }
        }).catch((error:any) => Observable.throw(error.json().error || 'Server error'));
}

【问题讨论】:

    标签: angular angular5


    【解决方案1】:

    由于使用的是Behavior Subject,所以不必调用agian函数,可以直接使用Subject如下,

     login() {
        this.loginService.login(this.user.name,this.user.password).subscribe(
          (response) => {
            this.loginService.loggedIn.next(true);
            this.router.navigate(['/home']);
          }, (error) => {
            this.loginService.loggedIn.next(false);
            if (error.status == 400) {
              this.showErrorAlert();
            } else {
              console.log(error);
            }
          });
      }
    

    【讨论】:

      【解决方案2】:

      正确的答案是我应该像这样使用订阅方法而不是管道:

        constructor(private loginService: LoginService){
          this.loginService.isLoggedIn().subscribe((isLoggedIn: boolean) =>
          {
            if (!isLoggedIn){
              this.loggedIn = false;
            }
            this.loggedIn = true;
          })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-12-25
        • 2022-12-11
        • 2021-09-05
        • 1970-01-01
        • 2019-09-15
        • 1970-01-01
        • 2021-12-25
        • 1970-01-01
        相关资源
        最近更新 更多