StivinKing
@StivinKing

Angular 2: Удаление элементов страницы в зависимости от роли?

Доброго времени суток,

продолжаю делать ролезависимую систему. Практически доделал роли на разделы (осталось придумать где лучше хранить роль пользователя). Сейчас же делаю роли на отдельные части раздела (к примеру скрыть убрать у обычного пользователя кнопку, или список, или ...)

Решил сделать директиву, пример кода ниже (роль на данный момент прописана статически):
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("Доступ запрещен");
        }
    }

}


И в шаблоне просто пишем на любом блоке:
<p [hasRole]="['admin', 'user']">Тестовый параграф которые видят только Админ и Пользователь</p>
<div [hasRole]="['admin']">Тестовый блок который видит только Админ</div>


Реагирует на правильность доступа правильно. Но вот this.viewContainerRef.clear(); не срабатывает. Все элементы остаются неизменными. Что я упустил?
  • Вопрос задан
  • 1693 просмотра
Решения вопроса 1
Вы упустили то, что в вашем случае директива выступает как бы хостом для элементов, но вы ничего не добавляли в этот контейнер под названием viewContainerRef.

Попробуйте написать структурную директиву как это:

@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("Доступ запрещен");
        }
    }
}


Используйте просто со звездочкой

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


Это аналогично этому

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

Т.е. здесь template(будет текстовой нодой) выступает в роли хоста-контейнера для элементов. И мы в зависимости от наших условий решаем - добавлять или нет эти элементы в контейнер, которые пойдут следом за хостом. Если планируете динамически менять права, то можете использовать сеттер для инпута. Вот вам шаблон https://github.com/angular/angular/blob/2.4.5/modu...
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы