230 votes

Le "composant" d'Angular 2 n'est pas un élément connu.

J'essaie d'utiliser un composant que j'ai créé dans le AppModule dans d'autres modules. J'obtiens cependant l'erreur suivante :

"Uncaught (in promise) : Error : Erreurs d'analyse du modèle :

'contacts-box' n'est pas un élément connu :

  1. Si "contacts-box" est un composant Angular, vérifiez qu'il fait partie de ce module.
  2. Si 'contacts-box' est un composant Web, ajoutez 'CUSTOM_ELEMENTS_SCHEMA' à '@NgModule.schemas' de ce composant pour supprimer ce message.

La structure de mon projet est assez simple : Overall project structure

Je conserve mes pages dans le répertoire pages, où chaque page est conservée dans un module différent (par exemple le module customers) et chaque module a plusieurs composants (comme le composant customers-list, le composant customers-add et ainsi de suite). Je veux utiliser mon ContactBoxComponent à l'intérieur de ces composants (donc à l'intérieur de customers-add-component par exemple).

Comme vous pouvez le voir, j'ai créé le composant ContactBox dans le répertoire des widgets, il se trouve donc dans le AppModule. J'ai ajouté l'import ContactBoxComponent à app.module.ts et je l'ai mis dans la liste des déclarations de AppModule. Cela n'a pas fonctionné, alors j'ai cherché mon problème sur Google et j'ai ajouté ContactBoxComponent à la liste des exportations. Cela n'a pas aidé. J'ai aussi essayé de mettre ContactBoxComponent dans CustomersAddComponent et ensuite dans un autre (d'un module différent) mais j'ai eu une erreur disant qu'il y a plusieurs déclarations.

Qu'est-ce que je rate ?

2 votes

La structure de vos dossiers n'est pas simple. Elle est confuse. Je vous suggère de suivre le guide de style d'Angular (lien non fourni car ils changent) et d'utiliser leurs suggestions de structure de dossiers, puis de vous assurer que vous utilisez correctement les modules. C'est ce que cela signifie. Vous n'exportez pas ou ne déclarez pas votre composant dans un module ingéré par l'application à un moment donné.

6 votes

Quelle réponse utile à la question posée...

1 votes

J'ai eu ce problème et je l'ai résolu en incluant un composant là où il n'était pas inclus mais où il y avait un composant qui l'incluait. Ce que je veux dire... J'ai lu TOUTES les réponses ci-dessous et j'ai essayé beaucoup de choses avant de trouver ma solution... toutes les contributions sont bonnes et je vous recommande d'en lire plus d'une. HTH

439voto

Robin Dijkhof Points 8254

Voici les 5 étapes que je réalise lorsque je reçois une telle erreur.

  • Êtes-vous sûr que le nom est correct ? (Vérifiez également le sélecteur défini dans le composant)
  • Déclarer le composant dans un module ?
  • S'il se trouve dans un autre module, exporter le composant ?
  • S'il se trouve dans un autre module, importez ce module ?
  • Redémarrer le cli ?

Lorsque l'erreur se produit pendant les tests unitaires, assurez-vous que vous avez déclaré le composant ou importé le module dans le fichier TestBed.configureTestingModule

J'ai également essayé de mettre ContactBoxComponent dans CustomersAddComponent et ensuite dans un autre (d'un module différent) mais j'ai obtenu une erreur disant qu'il y a des déclarations multiples.

Vous ne pouvez pas déclarer un composant deux fois. Vous devez déclarer et exporter votre composant dans un nouveau module séparé. Ensuite, vous devez importer ce nouveau module dans chaque module dans lequel vous souhaitez utiliser votre composant.

Il est difficile de dire quand vous devez créer un nouveau module et quand vous ne devez pas le faire. Je crée généralement un nouveau module pour chaque composant que je réutilise. Lorsque j'ai des composants que j'utilise presque partout, je les mets dans un seul module. Quand j'ai un composant que je ne réutilise pas, je ne crée pas de module séparé jusqu'à ce que j'en aie besoin ailleurs.

Bien qu'il puisse être tentant de mettre tous vos composants dans un seul module, cela est mauvais pour les performances. Pendant le développement, un module doit être recompilé à chaque fois que des modifications sont apportées. Plus le module est gros (plus il y a de composants), plus cela prend du temps. Apporter un petit changement à un gros module prend plus de temps que d'apporter un petit changement à un petit module.

10 votes

Vos étapes ne m'ont pas aidé mais c'est peut-être parce que je suis assez nouveau dans Angular 2, alors je vais y répondre et peut-être que nous trouverons la solution ensemble. Je suis sûr que le nom est correct, j'ai déclaré le composant dans AppModule, j'ai exporté le composant dans AppModule et redémarré le cli. J'ai également essayé d'importer AppModule dans mon composant CustomersAddComponent mais le résultat est Error : Maximum call stack size exceeded (Je suppose que nous n'importons pas AppModule dans Angular 2).

8 votes

Vous devez déclarer et exporter votre composant dans un module séparé, pas dans AppModule. Ensuite, vous devez importer ce nouveau module dans tous les modules dans lesquels vous souhaitez utiliser votre composant.

2 votes

Ok, je comprends maintenant. La seule question qui se pose est la suivante : lorsque j'importe le module nouvellement créé (disons WidgetsModule), il charge tous les composants déclarés à l'intérieur, n'est-ce pas ? C'est une certaine surcharge mais peut-être que je comprends mal quelque chose. Je pourrais bien sûr créer ContactsBoxModule mais cela fait beaucoup pour un seul petit composant. Des conseils ?

43voto

Jan Hettich Points 1504

J'ai eu un problème similaire. Il s'est avéré que ng generate component (utilisant la version 7.1.4 du CLI) ajoute une déclaration pour le composant enfant au AppModule, mais pas au module TestBed qui l'émule.

L'application exemple "Tour of Heroes" contient une HeroesComponent avec sélecteur app-heroes . L'application fonctionne bien lorsqu'elle est servie, mais ng test a produit ce message d'erreur : 'app-heroes' is not a known element . Ajout de la HeroesComponent manuellement aux déclarations dans configureTestingModule (en app.component.spec.ts ) élimine cette erreur.

describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent,
        HeroesComponent
      ],
    }).compileComponents();
  }));

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  });
}

1 votes

C'était mon problème - j'ai oublié d'ajouter Import dans le fichier de test.

24voto

harryvederci Points 359

J'ai eu exactement le même problème. Avant d'essayer certaines des solutions proposées ici, vous pouvez vérifier si le composant vraiment ne fonctionne pas. Pour moi, l'erreur était affichée dans mon IDE (WebStorm), mais il s'est avéré que le code fonctionnait parfaitement lorsque je l'ai exécuté dans le navigateur.

Après avoir fermé le terminal (qui exécutait ng serve) et j'ai redémarré mon IDE, le message n'est plus apparu.

0 votes

Le problème est spécifique à l'identité. J'ai le même problème avec webstorm. Webstorm n'est pas informé des changements effectués avec angular-cli, vous devez donc redémarrer l'IDE pour qu'il " voie " les nouveaux composants !

2 votes

J'ai le même problème avec VS Code mais avec Ionic 2. Dans une page cela fonctionne. Dans un composant il y a l'erreur ion-* n'est pas un élément connu . J'ai essayé votre suggestion d'arrêter service ionique et redémarré l'IDE, mais rien ne fonctionne. Connaissez-vous une autre solution pour cela ? Au fait - le code fonctionne de toute façon.

1 votes

J'ai eu le même problème avec VSCode. Après avoir redémarré l'éditeur, le message a disparu.

3voto

milan Points 96

J'ai le même problème avec la version 2017.3 de php storm. Ceci le résout pour moi : forum de support intellij

Il s'agissait d'une erreur de largeur du service linguistique @angular : https://www.npmjs.com/package/@angular/language-service

0 votes

Ceci a également corrigé le problème pour webstorm 2018.3

1voto

Vladimir Mitic Points 31

J'ai eu le même problème, et cela s'est produit à cause d'un module de fonctionnalité différent qui a inclus ce composant par erreur. Lorsque je l'ai retiré de l'autre fonctionnalité, cela a fonctionné !

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