当用户仅在Angular中登录时,如何使此导航栏显示所需的链接?

问题描述 投票:1回答:2

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

这是代码:

令牌服务

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

Authguard服务

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

header.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,但不确定它是否可行。如何解决此问题并仅为外部用户显示登录和注册链接,并仅显示已登录用户的最后2个下拉菜单?

angular typescript angular6
2个回答
1
投票

1.)你需要避免在component's methods中调用html template。可以找到here的解释

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。


-1
投票

您可以使用检查用户是否已登录以完全禁用/隐藏链接。此检查应由服务器发送到您的客户端,并且应该有一个服务,其中包含任何组件要求的登录状态。在您的情况下,您可以在标签内添加结构指令*ngIf="user"以检查用户是否已设置,并且仅在设置时显示链接。

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

如果您只想保护路由,请使用AuthGuard。 https://angular.io/guide/router#canactivate-requiring-authentication

© www.soinside.com 2019 - 2024. All rights reserved.