I
I
Ivan Stroykin2017-01-30 19:34:53
Angular
Ivan Stroykin, 2017-01-30 19:34:53

Angular 2: Removing page elements based on role?

Good day,
I continue to make a role-dependent system. I practically completed the roles into sections (it remains to figure out where it is better to store the user role). Now I am making roles for separate parts of the section (for example, hide a button, or a list, or ... from a normal user).
I decided to make a directive, an example of the code is below (the role is currently registered statically):

import { Directive, OnInit, ViewContainerRef } from '@angular/core';
import { Input } from "@angular/core/src/metadata/directives";

@Directive({
    selector: '[hasRole]'
})
export class HasRoleDirective implements OnInit {

    @Input() hasRole: Array<string>;

    private viewContainerRef: ViewContainerRef;

    constructor(viewContainerRef: ViewContainerRef) {
        this.viewContainerRef = viewContainerRef;
    }

    ngOnInit() {
        this.checkRoles('user');
    }

    checkRoles(userRole: string) {
        console.log("Роль пользователя: " + userRole);
        if (!this.hasRole || this.hasRole.indexOf(userRole) != -1) {
            console.log("Есть доступ");
        } else {
            this.viewContainerRef.clear();
            console.log("Доступ запрещен");
        }
    }

}

And in the template we simply write on any block:
<p [hasRole]="['admin', 'user']">Тестовый параграф которые видят только Админ и Пользователь</p>
<div [hasRole]="['admin']">Тестовый блок который видит только Админ</div>

Responds to correct access correctly. But here is this.viewContainerRef.clear(); does not work. All elements remain unchanged. What did I miss?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey Zuev, 2017-01-30
@StivinKing

What you missed is that in your case the directive acts as a host for the elements, but you did not add anything to this container called viewContainerRef.
Try writing a structural directive like this:

@Directive({
    selector: '[hasRole]'
})
export class HasRoleDirective implements OnInit {
    @Input() hasRole: Array<string>;

    constructor(private viewContainerRef: ViewContainerRef, 
                       private template: TemplateRef<any>) {}

    ngOnInit() {
        this.checkRoles('user');
    }

    checkRoles(userRole: string) {
        console.log("Роль пользователя: " + userRole);
        if (!this.hasRole || this.hasRole.indexOf(userRole) != -1) {
            console.log("Есть доступ");
            this.viewContainerRef.createEmbeddedView(this.template);
        } else {
            this.viewContainerRef.clear();
            console.log("Доступ запрещен");
        }
    }
}

Use just with an asterisk
<p *hasRole="['admin', 'user']"><Блок идят только Админ и Пользователь</p>
<div *hasRole="['admin']">Тестовый блок который видит только Админ</div>

This is similar to this
<template [hasRole]="['admin', 'user']">
   <p>Тестовый параграф которые видят только Админ и Пользователь</p>
</template>
<template [hasRole]="['admin']">
   <div>Тестовый блок который видит только Админ</div>
</template>

Those. here template (which will be a text node) acts as a container host for the elements. And we, depending on our conditions, decide whether or not to add these elements to the container, which will follow the host. If you plan to change permissions dynamically, you can use a setter for the input. Here is the template https://github.com/angular/angular/blob/2.4.5/modu...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question