Angular. Нужна помощь в решении проблемы с вызовом syn c, используемым с AuthGuard и директивой - PullRequest
0 голосов
/ 08 мая 2020

Я ищу решение проблемы, связанной с моим проектом. У меня есть http-вызов для получения userPermissions, и у меня есть два места, где я его использую:

  1. Защита авторизации на маршруте
  2. Директива в шаблоне компонента
1009 Есть ли какой-нибудь «простой» способ сделать это без редукции?

Ниже вы можете найти пример кода, он не совсем такой же, но даст представление о том, что я пытаюсь сделать.

пользователь .service.ts

export class UserService {
  userPermissions: string[];

  constructor(private userApi: UserApi) {}

  getUserPermissions(): Promise<string[]> {
    return new Promise((resolve, reject) => {
      if (this.userPermissions) {
        resolve(this.userPermissions);
      } else {
        this.userApi.getCurrentUser()
          .subscribe((user) => {
            this.userPermissions = user.permissions;
            resolve(this.userPermission);
          }, (err) => {
             reject(err);
          });
      }
    });

  }
}

some.component.ts

@Component({
  template: `
     <div appAuth [roles]="['read', 'write']" #myAuth="appAuth"
          *ngIf="myAuth.hasAllRoles()">...</div>
  `
})

auth.directive.ts

@Directive({
  selector: 'appAuth'
})
export class AppAuth {
  @Input() roles: string[];

  constructor(private userService: UserService) {}

  async hasAllRoles() {
    const userPermissions = await this.userService.getUserPermissions();
    let guard = true;

    this.roles.forEach(role => {
      if (this.userPermissions.indexOf(role) === -1) {
        guard = false;
        break;
      }
    });

    return guard;
  }
}

app.module.ts

@NgModule({
  imports: [
    RouterModule.forRoot([
      { path: 'my-component', canActivate: [AuthGuard], data: { roles: ['write'] }, component: MyComponent }
    ])
  ]
})
export class AppModule {}

auth.guard.ts

export class AuthGuard implements CanActivate {
  constructor(private userService: UserService) {}

  canActivate(route: ActivatedRouteSnapshot) {
    return new Promise((resolve, reject) => {
      this.userService.getUserPermissions()
        .then(((userPermissions: string[]) => {
          if (route.data.roles) {
            let guard = true;

            route.data.roles.forEach(role => {
              if (userPermissions.indexOf(role) === -1) {
                guard = false;
                break;
              }
            });
            resolve(guard);
          } else {
            resolve(true);
          }
        });
    })
  }
}
...