Я имел дело с такими случаями, и вот что я обычно делаю:
1. Я создаю службу Resolver (которая реализует Resolve
интерфейс).Это позволяет вам получить все необходимые данные до активации маршрута:
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
import { DataService } from 'path/to/data.service';
@Injectable()
export class ExampleResolverService implements Resolve<any> {
constructor(private _dataService: DataService) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<any> {
return this._dataService.anyAsyncCall()
.then(response => {
/* Let's imagine, that this method returns response with field "result", which can be equal to "true" or "false" */
/* "setResult" just stores passed argument to "DataService" class property */
this._dataService.setResult(response.result);
})
.catch(err => this._dataService.setResult(false););
}
}
2. Вот как мы можем иметь дело с AuthGuard , который реализует CanActivate
интерфейс:
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import { DataService } from 'path/to/data.service';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private _dataService: DataService) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
/* "getResult" method operates with the same class property as setResult, it just returns the value of it */
return this._dataService.getResult(); // will return "true" or "false"
}
}
3. Затем вы можете включить Resolver и AuthGuard к вашей конфигурации маршрутов, здесь только часть (структура маршрутов может отличаться, вот пример с активацией родительского компонента):
const routes: Routes = [
{
path: 'app',
component: AppComponent,
resolve: {
result: ExampleResolverService // your resolver
},
canActivate: [AuthGuard], // your AuthGuard with "canActivate" method
children: [...] // child routes goes inside the array
}
];
Как это работает
Когда вы переходите к /app
, ExampleResolverService
запускается, выполняет API-вызов и сохраняет необходимую часть ответа на свойство класса в DataService
с помощью метода setResult
(это обычный установщик).Затем, когда распознаватель закончил работу, пришло время для нашего AuthGuard
.Он получает сохраненный результат из DataService
с помощью метода getResult
(это обычный метод получения) и возвращает этот логический результат (наш AuthGuard
ожидает, что логическое значение будет возвращено, и маршрут будет активирован, если он вернет true
, ине будет активирован, если вернет false
);
Это самый простой пример без каких-либо дополнительных операций с данными, обычно логика более сложная, но этого каркаса должно быть достаточно для базового понимания.