Подтвердить что ты не робот

Angular2 маршрутизатор добавляет компонент вместо замены

У меня есть приложение Angular2 с одной розеткой маршрутизатора, в которой отображаются разные компоненты, в зависимости от того, какая ссылка нажата в боковом меню.

Разметка для основного компонента, содержащего <router-outlet>, выглядит следующим образом:

<div *ngIf="authenticated == false">
  <app-login></app-login>
</div>
<div *ngIf="authenticated">
  <div class="page home-page">
    <header class="header">
      <app-navbar></app-navbar>
    </header>
    <div class="page-content d-flex align-items-stretch">
      <div class="sidebar-container">
        <app-sidebar-menu></app-sidebar-menu>
      </div>
      <div class="content-inner">
      <app-page-header></app-page-header>
        <div id="sub-content">
          <router-outlet></router-outlet>
        </div>
        <app-footer></app-footer>
      </div>
    </div>
  </div>
</div>

Если я нажму ссылку Demo, демонстрационный компонент будет визуализирован, но если я затем перейду по ссылке "Главная", домашний компонент будет отображаться над демо-компонентом в DOM. Щелчок по ним несколько раз приведет к DOM, подобному этому

<div _ngcontent-c0="" id="sub-content">
    <router-outlet _ngcontent-c0=""></router-outlet>
  <app-home _nghost-c6="">...</app-home>
  <app-demo _nghost-c7="">...</app-demo>
  <app-home _nghost-c6="">...</app-home> <!-- Why so many here? Should be just either one <app-home> or <app-demo>  -->
  <app-demo _nghost-c7="">...</app-demo>
  <app-home _nghost-c6="">...</app-home>
  <app-demo _nghost-c7="">...</app-demo>
  <app-footer _ngcontent-c0="" _nghost-c5="">...</app-footer>
</div>

Маршруты определяются как

export const router: Routes = [
    { path: 'demo', component: DemoComponent, canActivate: [AuthGuard] },
    { path: 'home', component: HomeComponent, canActivate: [AuthGuard] }
]

Как получилось, что <router-outlet> не заменяет компонент, а вместо этого добавляет еще один "экземпляр" компонента при переходе между маршрутами?

4b9b3361

Ответ 1

Используя метод исключения, я обнаружил, что виновником проблемы был модуль BrowserAnimations в моем app.module.ts. Удалив его из моего imports, проблема исчезла. Я рассмотрю создание Plunker, чтобы продемонстрировать его.

Update: Это описано в этой проблеме Github.

Обновление 2017-12-13: Теперь это исправлено с помощью этого PR, fix (animations): правильно восстановить и очистить DOM при сбоях CD.

Ответ 2

Это происходит также, когда компонент A выбрасывает ошибку, поэтому при переходе к компоненту B компонент A не может быть уничтожен из-за ошибки. Это ошибка с Angular. Пока они не исправит, найдите причину ошибки и исправьте ее. Проверьте консоль инструментов разработчика.

Ответ 3

У меня была очень похожая проблема, также с использованием Firebase.

См. компоненты, добавляемые к маршрутизатору

Однако я обнаружил, что проблема исходила от ошибки в одном из моих компонентов, не связанной с моей маршрутизацией. Один из компонентов имел ссылку на "FormsArray", который не использовался и искажался. Он бросил ошибки в консоли devtools, но я не думал проверять там, так как все было хорошо компилировано.

Не уверен, что это поможет кому угодно.

Ответ 4

Я не уверен, что это точно соответствует вашей ситуации, однако у меня были предыдущие компоненты, добавляемые к DOM при попытке загрузить другой маршрут, и, наконец, я понял, что использование Hash противоречило адресам компонент,

export const AppRouting = RouterModule.forRoot(маршруты, { useHash: false});

Это устранило все мои проблемы с нежелательными добавленными компонентами

Ответ 5

Я использовал NgZone внутри компонента, и мой маршрутизаторLink имел ту же проблему, без ошибок внутри консоли.

Изменил routerLink на (щелчок) внутри и вызвал такую ​​функцию:

constructor(
    (...)
    private zone: NgZone,
    (...)
  ) { }

goToPage() {
    this.zone.run(() => this.router.navigate(['/page']));
}