检查ACL访问后,需要根据“routerLink”隐藏菜单中的链接。我不想在app中的每个元素链接上使用angular指令“* ngIf”(需要在routerConfig定义上做全局)
内容可以在组件上使用注释 @CanActivate 进行控制,但需要隐藏菜单中的链接
我尝试使用覆盖“routerLink”指令来执行此操作,但在此指令中,覆盖后无法访问routerConfig中定义的扩展参数(资源和特权)
示例:
@Component({})
@RouteConfig([{
path: '/dashboard',
name: 'Dashboard',
component: DashboardComponent,
data: {'resource':'account', 'privilage':'show'}
}])
但无法访问“routerLink”中的此配置数据(routerData)。
有些想法怎么做?
第二版
多级菜单和stiil在从routerConfig定义访问(扩展数据配置)时遇到问题。
主要组件
@RouteConfig([
{ path:'/dashboard', name: 'DashboardLink', component: DashboardComponent, data: { res: 'dasboard', priv: 'show'}, useAsDefault: true },
{ path:'/user/...', name: 'UserLink', component: UserComponent, data: { res: 'user', priv: 'show'} },
])
@Component({
selector: 'main-app',
template: `
<ul class="left-menu">
<li><a secured [routerLink]="['UserLink']">User</a>
<ul>
<li><a secured [routerLink]="['ProfileLink']">Profile</a></li>
</ul>
</li>
<li><a secured [routerLink]="['HomeLink']">Home</a></li>
<li><a secured [routerLink]="['DashboardLink']">Dashboard</a></li>
</ul>
<router-outlet></router-outlet>
`
})
export class MainComponent {
}
用户组件
@RouteConfig([
{ path: '/profile', name: 'ProfileLink', component: ProfileComponent, data: {res: 'user', priv: 'details'} },
])
@Component({ ... })
export class UserComponent {
}
个人资料组件
@Component({ ... })
export class ProfileComponent {
}
我的安全指令
@Directive({
selector: '[secured]'
})
export class SecuredDirective {
@Input('routerLink')
routeParams: any[];
/**
*
*/
constructor(private _viewContainer: ViewContainerRef, private _elementRef: ElementRef, private router:Router) {
}
ngAfterViewInit(){
//Get access to the directives element router instructions (with parent instructions)
let instruction = this.router.generate(this.routeParams);
//Find last child element od instruction - I thing thats my component but I am not sure (work good with two levels of menu)
this.getRouterChild(instruction);
}
private getRouterChild(obj: any){
var obj1 = obj;
while(true) {
if( typeof obj1.child !== 'undefined' && obj1.child !== null ){
obj1 = obj1.child;
} else {
break;
}
}
this.checkResPrivAcl(obj1.component.routeData.data)
}
private checkResPrivAcl(aclResAndPriv: any){
let hasAccess = CommonAclService.getInstance().hasAccess(aclResAndPriv['res'], aclResAndPriv['priv']);
if (!hasAccess) {
let el : HTMLElement = this._elementRef.nativeElement;
el.parentNode.removeChild(el);
}
console.log("CHECK ACL: " + aclResAndPriv['res'] + " | " + aclResAndPriv['priv']);
}
}
此解决方案仅适用于菜单的子项目,不适用于主菜单级别,并且不确定这在多级菜单上是否正常工作。
我尝试了不同的方法来解决这个问题我尝试在指令中访问RouterConfig定义(和我的routerData扩展配置)并使用 @Input('routerLink')<链接的别名来检查元素/ strong>但是没有找到如何访问RouterConfig。
答案 0 :(得分:3)
我认为你可以创建一个专门的指令来做到这一点。该指令将附加在包含routerLink
的HTML元素上。这样您就可以访问本机元素和RouterLink
指令:
@Directive({
selector: '[secured]'
})
export class Secured {
constructor(private routerLink:RouterLink,private eltRef:ElementRef) {
(...)
}
}
并以这种方式使用它:
@Component({
selector: 'app',
template: `
<router-outlet></router-outlet>
<a secured [routerLink]="['./Home']">Home</a>
`,
providers: [ ROUTER_PROVIDERS ],
directives: [ ROUTER_DIRECTIVES, Secured ],
pipes: []
})
@RouteConfig([
{
path: '/home',
name: 'Home',
component: HomeComponent,
useAsDefault: true,
data: {'resources':'account', 'privilages':'show'}
},
(...)
])
export class ...
基于RouterLink
指令实例,您可以在定义路径时访问您指定的数据,并在必要时隐藏元素:
export class Secured {
@HostBinding('hidden')
hideRouterLink:boolean;
constructor(private routerLink:RouterLink) {
}
ngAfterViewInit()
var data = this.routerLink._navigationInstruction.component.routeData.data;
this.hideRouterLink = this.shouldBeHidden(data);
}
(...)
}
请参阅src/app.ts
修改强>
根据the issue Brandon中的建议,我们可以从routerLink
属性中指定的值重新生成组件指令:
export class Secured {
@HostBinding('hidden')
hideRouterLink:boolean;
@Input('routerLink')
routeParams:string;
constructor(private router:Router) {
}
ngAfterViewInit() {
var instruction = this.router.generate(this.routeParams);
var data = instruction.component.routeData.data;
this.hideRouterLink = this.shouldBeHidden(data);
}
(...)
}
答案 1 :(得分:0)
当route2在angular2中变为活动状态时,默认情况下会向链接添加hide
类。
所以我通过此disable
或@Component({
selector: 'my-app',
// to hide it,
styles: [".router-link-active { Display: none;}"], //just add it in single line...
// to hide it,
styles: [".router-link-active { pointer-events: none;cursor: default;opacity: 0.6; }"], //just add it in single line...
template:'...'
)}
激活路线,
<script src="[filename][id].js"></script>