首页 > 解决方案 > 当用户仅在 Angular 中登录时,如何使此导航栏显示所需的链接?

问题描述

我试图让导航栏仅在用户未登录时显示登录和注册按钮,并在用户登录时显示消息和配置文件导航项。

这是代码:

令牌服务

...
  SetToken(token) {
    this.cookieService.set('chat_token', token);
  }

  GetToken() {
    return this.cookieService.get('chat_token');
  }

  DeleteToken() {
    this.cookieService.delete('chat_token');
  }

  GetPayload() {
    const token = this.GetToken();
    let payload;
    if (token) {
      payload = token.split('.')[1];
      payload = JSON.parse(window.atob(payload));
    }

    return payload.data;
  }
}

身份验证服务

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> | Promise<boolean> | boolean {
    const token = this.tokenService.GetToken();
    if (token) {
      return true;
    } else {
      this.router.navigate(['/']);
      return false;
    }
  }
}

头文件.ts

  constructor(public nav: HeaderService, private tokenService: TokenService,
    private router: Router,
    private usersService: UsersService,
    private msgService: MessageService
  ) {
    this.socket = io('http://localhost:3000');
  } 

  ngOnInit() {
    this.user = this.tokenService.GetPayload();
    ...  

HTML

<nav *ngIf="nav.visible" class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="#">
    <img src="../assets/images/close.png" class="img-fluid" style="width:50px; height:50px" alt="">
  </a>

  <button class="navbar-toggler" type="button"
  (click)="toggleNavbar()">
<span class="navbar-toggler-icon"></span>
</button>


<div class="collapse navbar-collapse"
[ngClass]="{ 'show': navbarOpen }">
<ul class="navbar-nav ml-auto">

      <li class="nav-item">
        <a class="nav-link" routerLink="/home" >Item 1</a>
      </li>

      <li class="nav-item signin">
        <a class="nav-link" routerLink="/sign-in" >Sign in</a>
      </li>

       <li class="nav-item signup">
        <a class="nav-link" routerLink="/sign-up" >Sign Up</a>
      </li>
      <li class="nav-item dropdown ml-auto" appdropdown #r="appdropdown">

          <a class="nav-link dropdown-toggle toolbar-image" href="" onclick="return false;" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
              <i class="material-icons">forum</i>
            <span>2</span> 
          </a>
          <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownMenuLink">
              <div class="sidebar-scroll" id="list-group">
            <a class="dropdown-item chat" href="#">

                        <img src="http://emilcarlsson.se/assets/donnapaulsen.png" class="rounded-circle">
                        <div class='message'>
                        <h3 class="d-xs-none username">Jessica</h3>
                        <p class="d-xs-none letter">StanIsLove aaaaaaaaaaaaaaaaa.</p>
                        </div>
                        <p>17m ago</p>
                      </a>
                </div>
            </div>

        </li>
        <li class="nav-item dropdown ml-auto" appdropdown #r="appdropdown">
            <a class="nav-link dropdown-toggle" href="" onclick="return false;" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <img src="http://emilcarlsson.se/assets/donnapaulsen.png" class="rounded-circle profile">
            </a>
            <div class="dropdown-menu dropdown-menu-right avatar" aria-labelledby="navbarDropdownMenuLink">
                <div class="sidebar-scroll" id="list-group">
              <a class="dropdown-item chat" href="#">
                  <span class="d-xs-none username">Profile</span>  
                        </a>
                        <a class="dropdown-item chat" href="#">
                            <span class="d-xs-none username">Settings</span>  
                                  </a>
                                  <a class="dropdown-item chat" href="#">
                                    <span class="d-xs-none username">Logout</span>  
                                          </a>

                  </div>
              </div>


          </li>

    </ul>
  </div>
</nav>

我假设我应该在 HTML 中集成this.tokenService.GetPayload()并使用 ng if 但不确定它是否会起作用。如何解决此问题并仅为外部用户显示登录和注册链接,并仅为登录用户显示最后 2 个下拉菜单?

标签: angulartypescriptangular6

解决方案


1.) 你需要避免component's methods在你的html template. 可以在这里找到解释

2.)在您的内部header-component.ts,将您的服务注入构造函数,添加一个类属性,调用您的服务以获取令牌并相应地设置您的类属性。

export clas HeaderComponent implements OnInit:

  private isLogged: boolean;

constructor(private tokenService: TokenService){

  public ngOnInit() { 
    this.isLogged = this.tokenService.GetPayload() !== null; // here, I consider that user is logged if you have a payload, maybe you need to change the condition
  }
}

3.)在您header.component.html的内部,检查用户是否已登录以显示您的元素。

<div *ngIf="isLogged">...</div>

4.) 你的方法 GetPayload() 应该被修改。如果您没有令牌,您的代码将抛出TypeError: Cannot read property data of undefined

GetPayload() {
    const token = this.GetToken();
    if (!token) {
      return null;
    }
    const payload = Json.parse(window.atob(token.split('.')[1]);
    return payload.data;
  }

既然你的方法 GetPayload 可以返回 null,那么在调用方法时要小心,确保结果不为 null 后再使用。


推荐阅读