Encyclopédie des erreurs

Collision lors de la génération d'identifiants de composants

Lors de la création des composants, Angular génère un identifiant de composant unique pour chaque composant. Il est généré à partir des métadonnées du composant Angular, notamment (liste non exhaustive) : les selectors, le nombre de host bindings, les noms des propriétés de la classe, les view queries et les content queries. Lorsque les métadonnées de deux composants sont identiques (souvent parce qu'ils partagent le même selector), une collision de génération d'identifiant se produit.

Les identifiants de composants sont utilisés en interne par Angular :

  • pour des annotations supplémentaires sur les nœuds du DOM, liées à l'encapsulation des styles ;
  • pendant l'hydratation, pour restaurer l'état d'une application après un rendu côté serveur.

Pour éviter les problèmes que pourrait causer une collision d'identifiants de composants, il est recommandé de la résoudre comme décrit ci-dessous.

Exemple de collision d'identifiants de composants

@Component({
  selector: 'my-component',
  template: 'complex-template',
})
class Some {}

@Component({
  selector: 'my-component',
  template: 'empty-template',
})
class SomeMocked {}

La définition de ces deux composants déclenche une collision de génération d'identifiant, et un avertissement est affiché en mode développement.

Déboguer l'erreur

Le message d'avertissement inclut le nom de classe des deux composants dont les identifiants entrent en collision.

Le problème peut être résolu avec l'une des solutions ci-dessous :

  1. Modifiez le selector de l'un des deux composants. Par exemple, en utilisant une pseudo-classe sans effet comme :not() avec un nom de balise différent.

    @Component({
      selector: 'my-component:not(p)',
      template: 'empty-template',
    })
    class SomeMocked {}
  2. Ajoutez un attribut supplémentaire sur le host de l'un des composants.

    @Component({
      selector: 'my-component',
      template: 'complex-template',
      host: {'some-binding': 'some-value'},
    })
    class Some {}