仅当用户在Angular 2+;中登录或注销时,如何显示元素;?

仅当用户在Angular 2+;中登录或注销时,如何显示元素;?,angular,rxjs,angular-routing,angular-observable,Angular,Rxjs,Angular Routing,Angular Observable,我正在开发一个Angular 2+应用程序。我发现在AngularJS中实现一些相对简单的东西非常困难 我希望我的顶部导航在用户未登录时显示登录按钮,在用户未登录时显示注销按钮 我一直在尝试各种各样的东西,但我不能让它正常工作。我希望它在整个应用程序中都能保持一致的工作状态,而不管是否重新加载(它将isLoggedIn存储到localStorage) 我当前的实现根本不起作用,但我将在这里分享它,这样您就可以告诉我我是否至少在正确的轨道上 顶部导航.component.html <p c

我正在开发一个Angular 2+应用程序。我发现在AngularJS中实现一些相对简单的东西非常困难

我希望我的顶部导航在用户未登录时显示登录按钮,在用户未登录时显示注销按钮

我一直在尝试各种各样的东西,但我不能让它正常工作。我希望它在整个应用程序中都能保持一致的工作状态,而不管是否重新加载(它将
isLoggedIn
存储到
localStorage


我当前的实现根本不起作用,但我将在这里分享它,这样您就可以告诉我我是否至少在正确的轨道上

顶部导航.component.html

<p class="nav-item my-2 my-lg-0" *ngIf="!isLoggedIn | async"><a class="nav-link" routerLink="/login" routerLinkActive="active">Login</a></p>
  <p class="nav-item my-2 my-lg-0" *ngIf="isLoggedIn | async"><a class="nav-link" routerLink="//logout" routerLinkActive="active">Logout</a></p>
登录

注销

顶部导航.component.ts

export class TopNavigationComponent implements OnInit {

  @ViewChild('topnav') topnav: ElementRef;
  //isLoggedIn: boolean;

  isLoggedIn: Observable<Boolean>;

  constructor( private authService: AuthService, private logger: LoggerService ) { }

  ngOnInit() {
    this.isLoggedIn = this.authService.getIsLoggedIn();
  }
@Injectable()
export class AuthService {

  loggedIn$: Subject<Boolean> = new Subject<Boolean>();

  constructor(private logger: LoggerService) {
    let isLoggedInLocalStore = (localStorage.getItem('isLoggedIn') === 'true');
    if (!isLoggedInLocalStore) {
      isLoggedInLocalStore = false;
      localStorage.setItem('isLoggedIn', isLoggedInLocalStore.toString());
    }
  }

  getIsLoggedIn(): Observable<Boolean> {
    //return (localStorage.getItem('isLoggedIn') === 'true');
    return this.loggedIn$.asObservable();
  }

  login(): void {
    // TODO
    this.logger.log("AuthService | Login clicked...");
    localStorage.setItem('isLoggedIn', 'true');
    this.loggedIn$.next(true);
  }

  logout() {
    // TODO
    localStorage.setItem('isLoggedIn', 'false');
    this.loggedIn$.next(false);
  }

}
导出类TopNavigationComponent实现OnInit{
@ViewChild('topnav')topnav:ElementRef;
//伊斯洛格丁:布尔;
isLoggedIn:可观察;
构造函数(私有authService:authService,私有记录器:LoggerService){}
恩戈尼尼特(){
this.isLoggedIn=this.authService.getIsLoggedIn();
}
auth.service.ts

export class TopNavigationComponent implements OnInit {

  @ViewChild('topnav') topnav: ElementRef;
  //isLoggedIn: boolean;

  isLoggedIn: Observable<Boolean>;

  constructor( private authService: AuthService, private logger: LoggerService ) { }

  ngOnInit() {
    this.isLoggedIn = this.authService.getIsLoggedIn();
  }
@Injectable()
export class AuthService {

  loggedIn$: Subject<Boolean> = new Subject<Boolean>();

  constructor(private logger: LoggerService) {
    let isLoggedInLocalStore = (localStorage.getItem('isLoggedIn') === 'true');
    if (!isLoggedInLocalStore) {
      isLoggedInLocalStore = false;
      localStorage.setItem('isLoggedIn', isLoggedInLocalStore.toString());
    }
  }

  getIsLoggedIn(): Observable<Boolean> {
    //return (localStorage.getItem('isLoggedIn') === 'true');
    return this.loggedIn$.asObservable();
  }

  login(): void {
    // TODO
    this.logger.log("AuthService | Login clicked...");
    localStorage.setItem('isLoggedIn', 'true');
    this.loggedIn$.next(true);
  }

  logout() {
    // TODO
    localStorage.setItem('isLoggedIn', 'false');
    this.loggedIn$.next(false);
  }

}
@Injectable()
导出类身份验证服务{
loggedIn$:主题=新主题();
构造函数(专用记录器:LoggerService){
让isLoggedInLocalStore=(localStorage.getItem('isLoggedIn')=='true');
如果(!isLoggedInLocalStore){
isLoggedInLocalStore=false;
setItem('isLoggedIn',isLoggedInLocalStore.toString());
}
}
getIsLoggedIn():可观察{
//返回(localStorage.getItem('isLoggedIn')='true');
返回此.loggedIn$.asObservable();
}
login():void{
//待办事项
this.logger.log(“AuthService | Login clicked…”);
setItem('isLoggedIn','true');
this.loggedIn$.next(true);
}
注销(){
//待办事项
setItem('isLoggedIn','false');
this.loggedIn$.next(false);
}
}

您现在看到的是一种使用中央处理器的方法,甚至可以用于此目的

您必须将其与本地存储结合使用。当用户登录时,您需要将数据保存在共享服务和本地存储中。因此,这将确保如果用户注销,您可以将所有数据保存在本地存储中,并检查用户是否登录

当他按下注销按钮时,从本地存储和共享服务中删除本地值

现在,如何在这里显示登录和注销按钮是事件发射器和共享服务发挥其魔力的地方。一旦您向共享服务添加值,它将发出一个可观察的消息,观察组件将关注该消息,并且在观察组件中使用If和Else来显示按钮


您使用的方法是正确的,但需要稍作修改:

在top-navigation.component.ts中:

isLoggedIn:boolean;

constructor(private cd:ChangeDetectorRef, private authService: AuthService, private logger: LoggerService ) { 
      this.authService.getIsLoggedIn().subscribe((loggedIn:boolean) => {
      this.isLoggedIn = loggedIn;
      this.cd.markForCheck();}
}
在auth.service.ts中:

getIsLoggedIn(): Subject<Boolean> {
    return this.loggedIn$;
}
getIsLoggedIn():主题{
返回此.loggedIn$;
}
并从HTML中删除| async


每当用户登录时,您都会发送true,并从服务中抛出您的主题,所有订户都会收到通知,用户注销时也会收到通知。

我不确定我的回答是否对您有帮助。为此,我创建了名为GlobalEventsManager的服务

import { Injectable } from '@angular/core';
import { BehaviorSubject } from "rxjs/BehaviorSubject";
import { Observable } from "rxjs/Observable";

@Injectable()
export class GlobalEventsManager {

    private _showMainMenu: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(null);
    public showMainMenuEmitter: Observable<boolean> = this._showMainMenu.asObservable();

    constructor() {
      this.showMainMenu(Boolean(localStorage.getItem('currentUser')));
    }

    showMainMenu(ifShow: boolean) {
      this._showMainMenu.next(ifShow);
    }


}
如何在组件中使用它(不是完整的代码,只是示例):

现在您有了布尔showmain菜单变量,具体取决于您的用户

PS:您还可以将此GlobalEventsManager用于其他目的。例如,管理应该影响您的应用程序的全局事件

PPS:大约一年前,我在stackoverflow上发现了类似的解决方案。只是我找不到链接。因此,我试图在这里描述解决方案


谢谢。希望能对你有所帮助。

我没有告诉你这是一个谷歌登录。然后你登录,然后它会有一个注销按钮,我想答案是上面提到的利用共享服务。这是我为我的项目做的事情,并以代码链接为例。同样在示例中,但它是巨大的,你可能需要一个如果你想看的话就看吧。