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() компонента, который отображается при нажатии кнопки возврата.

Другие вопросы по тегам