Angular2。如何隐藏(不渲染)菜单中的支票后接入链路? [英] Angular2. How to hide(no-render) the link in the menu after check access?

查看:408
本文介绍了Angular2。如何隐藏(不渲染)菜单中的支票后接入链路?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

需要根据routerLink后检查ACL访问隐藏在菜单链接。我不想用角指令* ngIf应用程序中的每一个元素链接(需要做的globaly在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访问我的扩展参数定义的(资源的privilages)

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

  (...)
}

请参阅本plunkr在的src / app.ts 文件:的 https://plnkr.co/edit/SBoFVo?p=$p$pview

See this plunkr in the src/app.ts file: https://plnkr.co/edit/SBoFVo?p=preview

修改

所建议的问题 https://github.com/angular/angular/issues/7641 通过布兰登( https://github.com/brandonroberts ),我们可以重新从组件指令在 routerLink 属性指定的值:

As suggested in the issue https://github.com/angular/angular/issues/7641 by Brandon (https://github.com/brandonroberts), 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);
  }

  (...)
}

这篇关于Angular2。如何隐藏(不渲染)菜单中的支票后接入链路?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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