Структурная директива Angular 7 работает только после обновления браузера

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

NavComponent.html:2 ОШИБКА TypeError: Не удается прочитать роль свойства неопределенного в HasRoleDirective.push../src/app/_directives/hasRole.directive.ts.HasRoleDirective.ngOnInit (hasRole.directive.ts:17) в checkAndUpdateDirectiveInline (core.js:20665) в checkAndUpdateNodeInline (core.js:21929) в checkAndUpdateNode (core.js:21891) в debugCheckAndUpdateNode (core.js:22525) в debugCheckDirectivesFn (core.js:22485) в Object.eval [как updateDirectives] (NavComponent.html:5) в Object.debugUpdateDirectives [как updateDirectives] (core.js:22477) в checkAndUpdateView (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>
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
0
635
3

Ответы 3

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

Предложение: кажется, что ваше свойство authService.decodedToken в какой-то момент не определено — вы можете использовать комбинацию RxJS subject / observable в своем 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).

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

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

Я не знаю, решали ли вы когда-нибудь это, но я думаю, что вы пытаетесь показать ссылку администратора перед входом в систему. Если вы не вошли в систему, у вас не будет токена для декодирования, и вы получите неопределенную ошибку.

Попробуйте поставить *ngIf=(loggedIn) в свой тег <ul>.

В вашем теге ul *

Kerb 11.08.2020 12:56

Другие вопросы по теме