Angular 9 - Невозможно отключить выход маршрутизатора на ленивом загруженном модуле
Обычно у меня есть компонент, который необходимо отображать условно при активации / деактивации named router-outlet
. Все в порядке со стороны активации, но это не работает, когда URL-адрес изменяется обратно (т.е. кто-то нажимает стрелку назад браузера): содержимое маршрутизатора все еще отображается. Думаю, основная проблема в том, что роутер-розетка является частью лениво загружаемого модуля. Я проверил этот предыдущий ответ для Angular 7, но он не влияет на мой проект (Angular 9).
Вот мои маршруты модуля маршрутизации
const routes: Routes = [
{ path: '', component: StudentsComponent },
{ path: ':id/macro',
component: StudentDetailComponent,
runGuardsAndResolvers: 'always',
resolve: {
item: StudentDetailResolverService,
macroAssignments: MacroAssignmentsResolverService
},
children: [
{
path: ':id/lto', // ***** PROBLEMS HERE ************************************
loadChildren: () => import('../lto/lto.module').then(m => m.LTOModule),
runGuardsAndResolvers: 'always',
}
]
}
];
И это шаблон, где router-outlet
директива
<app-item-detail>
...
<div *ngIf="!outlet.isActivated" list >
<app-student-detail-macro-list [student]="this.item" [macroAssignments]="this.macroAssignments" ></app-student-detail-macro-list>
</div>
</app-item-detail>
<router-outlet #outlet="outlet" name='lto-list' (deactivate)='checkOutlet($event)' (activate)='checkOutlet($event)' ></router-outlet>
ПРИМЕЧАНИЕ: checkOutlet($event) - это просто тест для печати чего-либо на консоли, когда встроенный эмиттер событий router-outlet что-то запускает. Это привело меня к обнаружению, что событие правильно запускается при активации выхода маршрутизатора, но ничего не происходит, когда URL-адрес возвращается обратно (поэтому выход маршрутизатора должен отключиться).
Наконец, модуль маршрутизации ленивого загружаемого модуля LTOModule
const routes: Routes = [
{ path: '' , component: LtoListComponent, outlet: 'lto-list' },
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class LTORoutingModule { }
Не знаю, может ли это быть полезно, но вот также часть шаблона, в которой активируется мой роутер.
<li *ngFor="let macroAssignment of this.macroAssignments" >
<a [routerLink]="[macroAssignment.macro, 'lto']" >
<span >{{ macroAssignment.macro_name }}</span>
</a>
</li>
**************** РЕДАКТИРОВАТЬ *****************
Я заметил, что когда вместо этого нажимаю стрелку вперед, я получаю следующую ошибку: ERROR Error: Uncaught (in promise): Error: Cannot activate an already activated outlet
2 ответа
Я нашел это (уродливое, ИМХО) обходное решение. В компоненте, который содержит директиву router-outlet, я подписываюсь на событие router, чтобы отслеживать изменения в URL-адресе при первой активации router-outlet. Затем, когда URL-адрес возвращается к тому, который соответствует пути родительского компонента, я деактивирую маршрутизатор-выход.
onActiveOutlet(component: Component) {
let previousUrl = this.router.url;
this.router.events.subscribe(
event => {
if (event instanceof NavigationEnd) {
if (previousUrl != this.router.url && previousUrl.includes(this.router.url)) {
this.outlet.deactivate();
}
}
}
)
}
А в шаблоне родительского компонента просто перехватите событие, генерируемое розеткой при ее активации.
<router-outlet #outlet="outlet" name='lto-list' (activate)='onActiveOutlet($event)' ></router-outlet>
Я думаю, это не имеет отношения к ленивой загрузке. Вам просто нужно сбросить условия, реализовав ngOnDestroy() компонента, который отображается при нажатии кнопки возврата.