Структурная директива Angular 7 работает только после обновления браузера - PullRequest
0 голосов
/ 14 февраля 2019

Я использую структурную директиву под углом от 7 до 7, чтобы скрыть части приложения в зависимости от роли пользователя.роль пользователя декодируется из токена jwt.Однако я сталкиваюсь с проблемами.Я использовал ту же реализацию с Angular 6, и у меня не было проблем, но все, что я пробовал, похоже, не работает.если я захожу как администратор, мне нужно обновить браузер, чтобы ссылка администратора отображалась или была скрыта, если я захожу как обычный пользователь.сообщение об ошибке было опубликовано ниже, и я добавил hasRole.directive и ссылку html

NavComponent.html: 2 ОШИБКА TypeError: Невозможно прочитать свойство 'role' undefined в HasRoleDirective.push ../ src /app / _directives / hasRole.directive.ts.HasRoleDirective.ngOnInit (hasRole.directive.ts: 17) в checkAndUpdateDirectiveInline (core.js: 20665) в checkAndUpdateNodeInline (core.js: 21929) в checkAndUdAdUpdebugCheckAndUpdateNode (core.js: 22525) в debugCheckDirectivesFn (core.js: 22485) в Object.eval [в качестве updateDirectives] (NavComponent.html: 5) в Object.debugUpdateDirectives [в качестве updateDirectives]: в качестве updateDirectives для проверки подлинности (в качестве элемента updateUp4) для проверки подлинности 22-го уровня в качестве объектаcore.js: 21873) в callViewAction (core.js: 22114)

import { Directive, Input, ViewContainerRef, TemplateRef, OnInit } from '@angular/core';
import { AuthService } from '../_services/auth.service';

@Directive({
  selector: '[appHasRole]'
})
export class HasRoleDirective implements OnInit {
  @Input() appHasRole: string[];
  isVisible = false;

  constructor(
    private viewContainerRef: ViewContainerRef,
    private templateRef: TemplateRef<any>,
    private authService: AuthService) { }

  ngOnInit() {
    const userRoles = this.authService.decodedToken.role as Array<string>;
    // if no roles clear the view container ref
    if (!userRoles) {
      this.viewContainerRef.clear();
    }

    // if user has role needed then render the element
    if (this.authService.roleMatch(this.appHasRole)) {
      if (!this.isVisible) {
        this.isVisible = true;
        this.viewContainerRef.createEmbeddedView(this.templateRef);
      } else {
        this.isVisible = false;
        this.viewContainerRef.clear();
      }
    }
  }

}
<ul class="navbar-nav">
        <li *appHasRole="['Admin', 'Moderator']"  class="nav-item" routerLinkActive="active" >
            <a class="nav-link" [routerLink]="['/admin']"  id="side-menu">Admin</a>
          </li>

Ответы [ 2 ]

0 голосов
/ 17 июля 2019

Эта директива в порядке.Я без проблем использовал ту же директиву в Angular 6, 7 и 8.

  1. убедитесь, что ваша обычная роль пользователя передается в директиву
  2. Вы пытались переместитьдиректива для тега привязки внутри viewContainerRef?
    <a *appHasRole="['Admin', 'Moderator']" class="nav-link" [routerLink]="['/admin']"  id="side-menu">Admin</a>
0 голосов
/ 14 февраля 2019

Я использовал аналогичную концепцию в одном из моих проектов, чтобы показать или скрыть элементы DOM на основе разрешений текущего пользователя (= ~ роль).

Предложение: Кажется, ваше authService.decodedToken свойствов какой-то момент не определено - вы можете использовать предметную / наблюдаемую комбинацию RxJS в вашем authService для передачи ролей текущих пользователей подписчикам.Затем подпишитесь на это свойство в вашей директиве, чтобы показать или скрыть элемент.Моя реализация выглядит примерно так (фактическое показ / скрытие может быть другим, но вы все равно должны понимать мою точку зрения):

  ngOnInit() {
    this.shouldDisplay().subscribe((shouldDisplay) => {
      if (shouldDisplay && !this.hasView) {
        this.show();
      } else if (!shouldDisplay && this.hasView) {
        this.hide();
      }
    });
  }

  [...]

  shouldDisplay(): Observable<boolean> {
    return this.permissionService.isPermitted(this.permission);
  }

Метод isPermitted возвращает наблюдаемый результат, так как разрешения могутв моем случае все равно придется извлекать, когда директива запрашивает результат (это будет ваш токен аутентификации в этом случае, который может быть недоступен при рождении SPA).

...