36 votes

Le routeur Angular2 ajoute un composant au lieu de le remplacer

J'ai une application Angular2 avec une sortie de routeur qui affiche différents composants en fonction du lien cliqué dans un menu latéral.

Le balisage du composant principal contenant le <router-outlet> ressemble à ceci

<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>

Si je clique sur le bouton Démonstration le composant de démonstration est affiché, mais si je clique ensuite sur le lien Accueil le composant "home" est rendu au-dessus du composant "demo" dans le DOM. En cliquant plusieurs fois sur les deux composants, vous obtiendrez un DOM semblable à celui-ci

<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>

Les itinéraires sont définis comme suit

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

Comment se fait-il que le <router-outlet> ne remplace pas le composant, mais ajoute une autre "instance" du composant lors du passage d'un itinéraire à l'autre ?

1 votes

Wow ... il ne devrait certainement pas faire cela. Il remplace correctement le contenu dans mes applications utilisant un code similaire. Pouvez-vous faire un plunker qui reproduit l'erreur ? Ou fournir le code html pour le composant home dans votre question ci-dessus ?

0 votes

J'ai cru devenir fou ! Je travaille sur un plunker !

0 votes

Cela m'arrive également dans un composant d'onglets personnalisé. J'ai demandé à plusieurs personnes de l'examiner avec moi et je ne trouve rien. J'ai pensé que j'avais peut-être un *ngFor qui traînait quelque part et qui créait des divs pour chaque clic, mais ce n'est pas le problème. Si j'inspecte le code dans le navigateur, il montre le lien du routeur directement suivi d'une liste de composants qui est ajoutée à chaque clic. J'espère que quelqu'un pourra trouver une réponse rapidement.

55voto

Daniel B Points 5971

En utilisant la méthode de l'élimination, j'ai découvert que le coupable du problème était le BrowserAnimations dans mon module app.module.ts . En le retirant de mon imports le problème a disparu. Je vais essayer de créer un Plunker pour en faire la démonstration.

Mise à jour : Elle est décrite dans le présent document. Problème Github .

Mise à jour 2017-12-13 : Ce problème a été corrigé dans ce PR, fix(animations) : récupération et nettoyage corrects du DOM en cas de défaillance du CD .

2 votes

Merci pour cette clarification, c'est le message le plus important que j'ai lu de toute la journée ! Vous êtes fantastique.

0 votes

Heureux que cela vous ait aidé ! J'ai essayé de le recréer avec un Plunkr sans succès pour pouvoir déterminer s'il s'agit d'un bug ou non !

2 votes

Cela ne résout pas non plus le problème, c'est très étrange !

25voto

TetraDev Points 6268

C'est également le cas lorsque le composant A génère une erreur Ainsi, lors de la navigation vers le composant B, le composant A n'a pas pu être détruit à cause de l'erreur. Il s'agit d'un bogue d'Angular. Jusqu'à ce qu'il soit corrigé, trouvez la cause de l'erreur et corrigez-la. Vérifiez la console de vos outils de développement.

0 votes

Dans mon cas, il s'agissait d'un composant parent qui contenait une erreur (qui semble inoffensive à première vue) et qui causait apparemment l'APPENDING au lieu du REPLACING. Merci de me l'avoir signalé.

0 votes

Merci, cela m'a aidé. Dans mon cas, cela se produisait si l'un des composants avait une erreur !

0 votes

Merci de votre attention ! J'étais confronté au même problème et il n'y avait pas d'erreur dans la console lorsque je naviguais vers le composant B. Ce problème peut survenir lorsque vous ne voyez pas d'erreurs dans la console également. Dans mon cas, la solution était la suivante : Code original : this.obj1 = obj2 ; Code corrigé : this.obj1 = _.extend(this.obj1, obj2) ;

7voto

J'ai eu un problème très similaire, en utilisant également Firebase.

Voir les composants ajoutés à la sortie du routeur

Cependant, j'ai découvert que le problème provenait d'une erreur dans l'un de mes composants, sans rapport avec mon routage. Un des composants avait une référence à un "FormsArray", qui n'était pas utilisé et malformé. Cela générait des erreurs dans la console devtools, mais je n'ai pas pensé à vérifier, puisque tout se compilait bien.

Je ne sais pas si cela aidera quelqu'un.

0 votes

Cela m'a aidé ! Mon problème était qu'un nouveau composant enfant ne se rendait pas complètement (utilisation d'un tube de date pour des données erronées). Dans ce cas, Angular affichait des données partielles pour le nouveau et l'ancien composant, l'un après l'autre. Dès que j'ai corrigé le problème du pipe, le problème s'est résolu. Merci beaucoup pour cette astuce !

1 votes

Comment avez-vous débogué ? J'ai le même problème ! Pouvez-vous montrer les changements de code que vous avez effectués ?

0 votes

J'ai le même problème que @Mrworldwide. C'est l'une des choses que je n'aime pas dans l'utilisation des frameworks, il est parfois impossible de déboguer.

3voto

António Santos Points 21

J'utilisais NgZone dans le composant et mon routerLink avait le même problème, sans aucune erreur dans la console.

J'ai remplacé le routerLink par un (click) à l'intérieur et j'ai appelé une fonction comme celle-ci :

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

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

1voto

Hassan Juniedi Points 135

J'ai eu un problème similaire, et la raison est que j'ai utilisé une directive qui n'est pas déclarée dans le composant A et il n'y avait pas d'erreur dans la compilation ou la console. Ainsi, lorsque je navigue vers le composant B, le routeur ajoute le contenu.

Pour déboguer, j'ai commenté toutes les balises html dans les deux composants en ne laissant qu'un h1 pour voir si le contenu était ajouté. Avec quelques tests, j'ai trouvé la directive et en la supprimant, le routeur est redevenu normal.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X