简体   繁体   English

我如何在登录中订阅更改

[英]How do I subscribe to changes in the Login

I have a navbar menu component which has optional links that depend on whether or not the user is logged in. In my current setup the navbar checks the login status (via the LoginService) on initialisation. 我有一个导航栏菜单组件,该组件具有取决于用户是否已登录的可选链接。在当前设置中,导航栏在初始化时检查登录状态(通过LoginService)。 Here is the NavMenuComponent.ts : 这是NavMenuComponent.ts

export class NavMenuComponent implements OnInit {
  isExpanded = false;
  isNavbarCollapsed = true;

  isLoggedIn: boolean;

  subscription: Subscription;

  constructor(private jwtHelper: JwtHelper, private loginService: LoginService) {

    this.subscription = loginService.checkLoginStatus.subscribe(
      isLoggedIn => {
        this.isLoggedIn = isLoggedIn
      });
  }

  ngOnInit() {
    //this.checkLoginStatus();
    this.isLoggedIn = this.loginService.checkLoginStatus();
  }

  collapse() {
    this.isExpanded = false;
  }

  toggle() {
    this.isExpanded = !this.isExpanded;
  }
}

I want the navbar menu component to react if the user logs in or out. 我希望导航栏菜单组件在用户登录或注销时做出反应。 That means publishing an event in either my in the LoginService or the LoginComponent which the navbar is subscribed. 这意味着在导航服务订阅的LoginService或LoginComponent中发布事件。 You can see that I have tried to write a subcription in the navbar menu, which doesn't work! 您可以看到我试图在导航栏菜单中写一个订阅,但是没用!

How should I get it to work? 我应该如何工作?

Edit : Here's the loginService: 编辑 :这是loginService:

export class LoginService {
  //isLoggedIn: boolean;

  constructor(private jwtHelper: JwtHelper) { }

  //checkLoginStatus(): Observable<boolean> {
   checkLoginStatus(): boolean {
    var token = localStorage.getItem("jwt");

    if (token && !this.jwtHelper.isTokenExpired(token)){
      //console.log(this.jwtHelper.decodeToken(token));
      alert("user is logged in");
      //this.isLoggedIn = true;

      return true;
    }
    else {
      //this.isLoggedIn = false;
      alert("user is NOT logged in");
      return false;

    }
  }
}

Assuming that loginService.checkLoginStatus is an Observable that is going to push new boolean values in either true or false as soon as the user performs login or logout, you can simply use that. 假设loginService.checkLoginStatus是一个Observable ,一旦用户执行登录或注销,它将以truefalse推送新的boolean值,则可以简单地使用它。

Actually, you're already using it. 实际上,您已经在使用它。 So whenever there's a change in the login state of the user, the isLoggedIn property on your Component will update. 因此,只要用户的登录状态发生变化,组件上的isLoggedIn属性就会更新。 So you should be able to directly use it in your template. 因此,您应该可以在模板中直接使用它。

Also, since that is the case, there's no need for the code that you have in ngOnInit . 另外,既然是这种情况,则不需要ngOnInit的代码。 As a matter of fact, you can move your constructor code to ngOnInit and refactor your code a bit. 实际上,您可以将constructor代码移至ngOnInitngOnInit重构代码。 Something like this: 像这样:

export class NavMenuComponent implements OnInit {
  isExpanded = false;
  isNavbarCollapsed = true;

  isLoggedIn: boolean;

  subscription: Subscription;

  constructor(
    private jwtHelper: JwtHelper, 
    private loginService: LoginService
  ) {}

  ngOnInit() {
    this.subscription = loginService.checkLoginStatus
      .subscribe(isLoggedIn => this.isLoggedIn = isLoggedIn);
  }

  ...
}

UPDATE: 更新:

I think you should create a private BehaviorSubject in your LoginService which you're then going to expose asObservable publicly. 我认为您应该在LoginService创建一个private BehaviorSubject ,然后将其公开公开为asObservable Now, once the user logs in, just call .next(true) on this private BehaviorSubject and when the user logs out, call .next(true) . 现在,一旦用户登录,只需在此私有BehaviorSubject上调用.next(true) ,然后在用户注销时,调用.next(true)

import { BehaviorSubject, Observable } from 'rxjs';

export class LoginService {

  private isLoggedIn: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
  isLoggedIn$: Observable<boolean> = this.isLoggedIn.asObservable();

  constructor(private jwtHelper: JwtHelper) {}

  ...

  // When Login
  this.isLoggedIn.next(true) 

  ...

  // When Logout
  this.isLoggedIn.next(false)

  /* checkLoginStatus(): boolean {
    var token = localStorage.getItem("jwt");

    (token && !this.jwtHelper.isTokenExpired(token)) ? this.isLoggedIn.next(true): this.isLoggedIn.next(false);
  } */
}

You can then subscribe to the public Observable the usual way in your Component. 然后,您可以在组件中按常规方式subscribe public Observable

Something like this: 像这样:

export class NavMenuComponent implements OnInit {
  isExpanded = false;
  isNavbarCollapsed = true;

  isLoggedIn: boolean;

  subscription: Subscription;

  constructor(
    private jwtHelper: JwtHelper, 
    private loginService: LoginService
  ) {}

  ngOnInit() {
    this.subscription = this.loginService.isLoggedIn$
      .subscribe(isLoggedIn => this.isLoggedIn = isLoggedIn);
  }

  ...
}

Below LoginService may be help you as I have added loggedStatus eventemitter object. 由于我已添加了loggingStatus eventemitter对象,因此在LoginService下面可能会为您提供帮助。 So when user log in or log out based on that particular value we are emitting and same value we will get in Nav component. 因此,当用户基于该特定值登录或注销时,我们正在发射,而我们将在Nav组件中获得相同的值。

export class LoginService {
      //isLoggedIn: boolean;
      loggedStatus = new EventEmitter<boolean>();

      constructor(private jwtHelper: JwtHelper) { }

      //checkLoginStatus(): Observable<boolean> {
       checkLoginStatus(): boolean {
        var token = localStorage.getItem("jwt");

        if (token && !this.jwtHelper.isTokenExpired(token)){
          //console.log(this.jwtHelper.decodeToken(token));
          alert("user is logged in");
          //this.isLoggedIn = true;
          this.loggedStatus.emit(true);
          return true;
        }
        else {
          //this.isLoggedIn = false;
          alert("user is NOT logged in");
          this.loggedStatus.emit(false);
          return false;

        }
      }
    }

Nav Component Change 导航组件更改

Below code you can implement in the ngOnInit method. 下面的代码可以在ngOnInit方法中实现。

this.loginService.loggedStatus.subscribe(
      isLoggedIn => {
        this.isLoggedIn = isLoggedIn
      });

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

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