angular - 当用户仅在 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 个下拉菜单?
解决方案
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 后再使用。
推荐阅读
- filtering - 我可以创建一个包含“链接记录”列中不存在的记录的 Airtable 视图吗?
- laravel - 从 laravel 中的 json 中删除枢轴键
- javascript - 如何选择生成多少个随机字符串?
- vue.js - 从 .js 文件 vuejs 访问组件
- ios - 将数据保存在来自 ios swift 中 2 个不同 uitableviews 的数组中
- xml - 努力理解 Google 表格 IMPORTXML 和 Xpath
- android - 是否可以使用 firebase ML 套件检测性别
- r - 找到两个文本之间的最大距离并绑定它们
- function-pointers - Emonlib+ADS1115+ESP32+Arduino 函数指针
- javascript - 赛普拉斯 - 断言仅存在一个带有文本的元素