检查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',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’)通过链接的别名来检查元素,但是没有找到怎样才能我可以访问RouterConfig.
我认为你可以创建一个专门的指令来做到这一点.该指令将附加在包含routerLink的同一HTML元素上.这样您就可以访问native元素和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文件中查看此plunkr:https://plnkr.co/edit/SBoFVo?p=preview
编辑
正如Brandon(https://github.com/brandonroberts)在https://github.com/angular/angular/issues/7641期刊中所建议的那样,我们可以从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); } (...) }