Подписка на наблюдаемые в маршрутных охранниках и их последствия - PullRequest
0 голосов
/ 22 октября 2018

У меня есть маршрутизатор, который называется PermissionGuard, который здесь инициируется

const routes: Routes = [
  {
    path: ':company',
    component: CompanyComponent,
    canActivate: [PermissionGuard],
    canActivateChild: [PermissionGuard],
    children: [
      {
        path: '',
        component: IndexComponent
      },
      {
        path: 'projects',
        loadChildren: '../projects/projects.module#ProjectsModule'
      },
    ]
  }
];

Внутри моего PermissionGuard я подписываюсь на PermissionService следующим образом:

export class PermissionGuard implements CanActivate, CanActivateChild {

  private permissions: Permission[];

  constructor(private permissionService: PermissionService, private router: Router) {
    this.permissionService.permissions$.subscribe(
      (permissions: Permission[]) => {
        this.permissions = permissions;
      }
    );
  }

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    this.permissionService.getPermissions(next.paramMap.get('company'));
    return this.permissionService.permissionsFetchDone$
    .pipe(filter(x => x))
    .pipe(
      map(response => {
        if (this.permissions) {
          return true;
        } else {
          this.router.navigate(['/forbidden']);
        }
      })
    );
  }
}

ивыполнить необходимые canActivate или canActivateChild проверки на основе этих данных.Из добавления console.log() и выдачи новых данных из permissions$ внутри дочерних маршрутов я вижу, что наблюдаемая все еще активна, даже если охрана «использовалась» и маршрут активирован.Затем я ожидал, что он исчезнет, ​​когда я пойду на маршрут за пределами path: ':company', однако охранник не будет уничтожен.

Это подводит меня к моему вопросу: Я делаю этоправильно?Я хочу использовать охрану, чтобы проверить, есть ли у пользователя какие-либо разрешения, но в то же время я хочу выполнить HTTP-запрос на разрешения только один раз (при переходе к path: ':company' или любому из его дочерних элементов).Боюсь, что если я буду использовать такие охранники, это со временем замедлит все приложение из-за огромного количества наблюдателей.

1 Ответ

0 голосов
/ 22 октября 2018

испуская новые данные из разрешений $ внутри дочерних маршрутов. Я вижу, что наблюдаемая все еще активна, даже если охрана "использовалась" и маршрут активирован.

Прежде всего, permissions$ все еще активен, потому что вы никогда не отписывались в своей охране.И angular создает сторожа как синглтон.

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

Это подводит меня к моему вопросу: правильно ли я делаю?Я хочу использовать охрану, чтобы проверить, есть ли у пользователя какие-либо разрешения,

Вполне нормально подать запрос в вашей охране, например, для получения разрешений.

но в то же время я хочу выполнить HTTP-запрос на разрешения только один раз (при переходе к пути: ': company' или любому из его дочерних элементов).

Если вы хотите только выполнить запросзатем вам следует подумать об использовании shareReplay в вашей службе аутентификации, чтобы все последующие подключающиеся экземпляры использовали одинаковые ранее выданные значения.

...