角2.检查访问权限后如何隐藏(不呈现)菜单中的链接? [英] Angular2. How to hide(no-render) the link in the menu after check access?

查看:16
本文介绍了角2.检查访问权限后如何隐藏(不呈现)菜单中的链接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

需要在检查 ACL 访问后根据 routerLink" 隐藏菜单中的链接.我不想在应用程序中的每个元素链接上使用角度指令 "*ngIf"(需要在 routerConfig 定义上全局执行)

Need to hide link in menu based on the "routerLink" after check ACL access. I do not want to use angular directives "*ngIf" on each element link in app (need to do that globaly on the routerConfig definition)

内容可以在组件上使用注解@CanActivate进行控制,但需要隐藏菜单中的链接

Content can controll using annotation @CanActivate on components but need to hide link in menu

我尝试使用覆盖 "routerLink" 指令来做到这一点,但是在覆盖之后的指令中无法访问我在 routerConfig 中定义的扩展参数(资源和权限)

I try do that with overwrite "routerLink" directive, but in this directives after overwrite can't get access to my extends param defined(resources and privilages) in routerConfig

示例:

@Component({})
@RouteConfig([{   
    path: '/dashboard', 
    name: 'Dashboard', 
    component: DashboardComponent, 
    data: {'resource':'account', 'privilage':'show'} 
}])

但是无法访问routerLink"中的这个配置数据(routerData).

But can't get access to this config data(routerData) in the "routerLink".

知道如何做到这一点吗?

Some idea how can do that?

第二版

多级菜单和 stiil 无法从 routerConfig 定义访问(扩展数据配置).

Multi level menu and stiil have problem with get access to the (extend data config) from routerConfig definition.

主要组件

@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']);
    }
}

此解决方案仅适用于菜单的子项,不适用于主菜单,并且不确定在多级菜单上是否正确.

This solution work only for child item of menu don't work with the main level of menu, and not sure is this work correctly on the multi level menu.

我尝试了不同的方法来解决这个问题我尝试访问指令中的 RouterConfig 定义(和我的 routerData 扩展配置),并使用 @Input('routerLink')<通过链接的别名检查元素 但找不到如何访问 RouterConfig.

I try diffrent way to resolve this problem I try get access to the RouterConfig definition (and my routerData extend config) in the directives and check element by the alias name of link using @Input('routerLink') but don't find how can I get access to the RouterConfig.

推荐答案

我认为你可以创建一个专门的指令来做到这一点.该指令将附加在包含 routerLink 的同一个 HTML 元素上.这样你就可以访问原生元素和 RouterLink 指令:

I think that you could create a dedicated directive to do that. This directive would be attach on the same HTML element that contains the routerLink one. This way you would have access to both native element and RouterLink directive:

@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 指令实例,您可以访问定义路由时指定的数据,并在必要时隐藏元素:

Based on the RouterLink directive instance, you can have access to the data you specified when defining the route and hide the element if necessary:

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代码>

编辑

正如 问题Brandon,我们可以从 routerLink 属性中指定的值重新生成组件指令:

As suggested in the issue by Brandon, we could regenerate the component instruction from the value specified in the routerLink attribute:

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

  (...)
}

这篇关于角2.检查访问权限后如何隐藏(不呈现)菜单中的链接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆