我正在使用角度为7到7的结构指令来根据用户角色隐藏应用程序的各个部分。用户角色从jwt令牌中解码。但是我遇到了问题。我已经在Angular 6中使用了相同的实现,并且没有问题,但是我尝试的一切似乎都没有效果。如果我以管理员身份登录,则我需要刷新浏览器以使管理员链接显示或隐藏(如果我以普通用户身份登录)。错误消息已发布在下面,并且我添加了hasRole.directive和html链接
NavComponent.html:2错误TypeError:无法读取未定义的属性“角色” 在HasRoleDirective.push ../ src / app / _directives / hasRole.directive.ts.HasRoleDirective.ngOnInit(hasRole.directive.ts:17) 在checkAndUpdateDirectiveInline(core.js:20665) 在checkAndUpdateNodeInline(core.js:21929) 在checkAndUpdateNode(core.js:21891) 在debugCheckAndUpdateNode(core.js:22525) 在debugCheckDirectivesFn(core.js:22485) 在Object.eval [作为updateDirectives](NavComponent.html:5) 在Object.debugUpdateDirectives [作为updateDirectives](core.js:22477) 在checkAndUpdateView(core.js:21873) 在callViewAction(core.js:22114)
import { Directive, Input, ViewContainerRef, TemplateRef, OnInit } from '@angular/core';
import { AuthService } from '../_services/auth.service';
@Directive({
selector: '[appHasRole]'
})
export class HasRoleDirective implements OnInit {
@Input() appHasRole: string[];
isVisible = false;
constructor(
private viewContainerRef: ViewContainerRef,
private templateRef: TemplateRef<any>,
private authService: AuthService) { }
ngOnInit() {
const userRoles = this.authService.decodedToken.role as Array<string>;
// if no roles clear the view container ref
if (!userRoles) {
this.viewContainerRef.clear();
}
// if user has role needed then render the element
if (this.authService.roleMatch(this.appHasRole)) {
if (!this.isVisible) {
this.isVisible = true;
this.viewContainerRef.createEmbeddedView(this.templateRef);
} else {
this.isVisible = false;
this.viewContainerRef.clear();
}
}
}
}
<ul class="navbar-nav">
<li *appHasRole="['Admin', 'Moderator']" class="nav-item" routerLinkActive="active" >
<a class="nav-link" [routerLink]="['/admin']" id="side-menu">Admin</a>
</li>
答案 0 :(得分:0)
我在我的一个项目中使用了类似的概念,以便根据当前用户的权限(=〜角色)显示或隐藏DOM元素。
建议:似乎您的authService.decodedToken
属性在某些时候未定义-您可以在authService
中使用RxJS主题/可观察的组合将当前用户的角色传播给订户。然后在指令中订阅该属性,以显示或隐藏该元素。我的实现看起来像这样(实际的显示/隐藏可能有所不同,但是您仍然应该明白我的意思):
ngOnInit() {
this.shouldDisplay().subscribe((shouldDisplay) => {
if (shouldDisplay && !this.hasView) {
this.show();
} else if (!shouldDisplay && this.hasView) {
this.hide();
}
});
}
[...]
shouldDisplay(): Observable<boolean> {
return this.permissionService.isPermitted(this.permission);
}
isPermitted
方法返回一个可观察到的结果,因为在我的情况下,当指令请求结果时可能仍需要获取许可权(在这种情况下,这将是您的auth令牌,可能不是在SPA出生时可用。
答案 1 :(得分:0)
此指令很好。我在Angular 6、7和8中使用了相同的指令,没有问题。
<a *appHasRole="['Admin', 'Moderator']" class="nav-link" [routerLink]="['/admin']" id="side-menu">Admin</a>
答案 2 :(得分:0)
我不知道您是否解决了这个问题,但是我认为您正在尝试在登录之前显示管理员链接。 如果您尚未登录,则将没有令牌可以解码,并且会收到未定义的错误。
尝试在您的*ngIf=(loggedIn)
标签中放置一个<ul>
。