我如何在登录名中订阅更改

时间:2018-12-21 12:55:37

标签: angular angular7

我有一个导航栏菜单组件,该组件具有取决于用户是否已登录的可选链接。在当前设置中,导航栏在初始化时检查登录状态(通过LoginService)。这是 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;
  }
}

我希望导航栏菜单组件在用户登录或注销时做出反应。这意味着在导航服务所订阅的LoginService或LoginComponent中以我的身份发布事件。您可以看到我试图在导航栏菜单中写一个订阅,但是没用!

我应该如何使它工作?

编辑:这是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;

    }
  }
}

2 个答案:

答案 0 :(得分:1)

假设loginService.checkLoginStatus是一个Observable,一旦用户执行登录或登录,它将在booleantrue中推送新的false值注销,您可以简单地使用它。

实际上,您已经在使用它。因此,只要用户的登录状态发生变化,组件上的isLoggedIn属性就会更新。因此,您应该可以直接在模板中使用它。

而且,既然是这种情况,就不需要您在ngOnInit中拥有的代码。实际上,您可以将constructor代码移至ngOnInit并稍微重构代码。像这样:

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

  ...
}

更新:

我认为您应该在private中创建一个BehaviorSubject LoginService,然后将其公开发布asObservable。现在,一旦用户登录,只需在此专用.next(true)上呼叫BehaviorSubject,然后在用户注销时,呼叫.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);
  } */
}

然后可以在组件中以通常的方式subscribepublic Observable

类似这样的东西:

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

  ...
}

答案 1 :(得分:1)

在LoginService下面,由于我添加了loggingStatus eventemitter对象,它可能会对您有所帮助。因此,当用户基于该特定值登录或注销时,我们正在发射,而在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;

        }
      }
    }

导航组件更改

下面的代码可以在ngOnInit方法中实现。

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