angular
April 21

Создание UrlTree из любого ActivatedRouteSnapshot в Angular

В текущей версии Angular, UrlTree может быть создан только из ActivatedRoute, который должен быть активным и присутствовать в UrlTree (то есть он не может быть пустым путем с именем outlet).

Из-за реализации текущего процесса создания UrlTree, UrlSegment ActivatedRoute ищется в текущем активном UrlTree маршрутизатора. Если это не срабатывает, то создание UrlTree завершается ошибкой.

В качестве примера рассмотрим ситуацию, когда у нас есть защита, которая, в зависимости от какого-то условия, перенаправляет на соседний маршрут:

@Injectable({ providedIn: 'root' })
export class MyGuard implements CanActivate {
  constructor(private router: Router, private route: ActivatedRoute) { }

  canActivate(route: ActivatedRouteSnapshot) {
    if(checkData(route)) {
      this.router.navigate(['../sibling'], { relativeTo: this.route }); 
      return false;
    }
    
    return true;
  }
}
const routes: Routes = [{
  path: 'parent',
  component: ParentComponent,
  children: [
    {
      path: 'child',
      component: ChildComponent,
      canActivate: [MyGuard]
    },
    {
      path: 'sibling',
      component: SiblingComponent
    }
  ]
}]

Поскольку соседний маршрут еще не активирован, это не сработает. Для решения этой проблемы маршрутизатор предоставляет новую функцию, которая позволяет создавать UrlTree из любого ActivatedRouteSnapshot:

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, createUrlTreeFromSnapshot } from '@angular/router';

@Injectable({ providedIn: 'root' })
export class MyGuard implements CanActivate {

  canActivate(route: ActivatedRouteSnapshot) {
    if(checkData(route)) {
      return createUrlTreeFromSnapshot(route, ['../sibling']);
    }
    
    return true;
  }
}

Функция CreateUrlTreeFromSnapshot принимает ActivatedRouteSnapshot, команды и необязательные queryParams и fragments, и возвращает UrlTree.