简体   繁体   English

如何将全局变量订阅到BehaviorSubject?

[英]How do I subscribe a global variable to a BehaviorSubject?

I'm building a login function and I want certain buttons in the app.component template to appear the moment the user has logged in. I am trying to use BehaviorSubject for this. 我正在构建一个登录功能,并且我希望用户登录后出现app.component模板中的某些按钮。为此,我尝试使用BehaviorSubject。 I'm using an *ngIf for the buttons in the template and the condition is a variable called loggedIn . 我使用的是*ngIf在模板中的按钮和状态是一个变量叫loggedIn However when I try to initialize the loggedIn variable with the result of the SubjectBehavior subscription i get the error: 但是,当我尝试使用SubjectBehavior订阅的结果初始化loginIn变量时,出现错误:

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

I don't know whats causing this because I am returning a boolean, not an observable. 我不知道是什么原因造成的,因为我返回的是布尔值,而不是可观察值。 Here is the code of app.component: 这是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();
  }

}

and heres the relevant code of the loginService: 这是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'));
}

Since you are using a Behavior Subject, you don't have to call the function agian, you can directly use the Subject as follows, 由于您使用的是行为主题,因此不必调用agian函数,您可以按照以下方式直接使用主题,

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

The correct answer is that i should use the subscribe method instead of pipe like so: 正确的答案是,我应该使用subscribe方法而不是像这样的管道:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM