typescript - Angular 2 'component' nu este un element cunoscut


Încerc să folosesc un component pe care l-am creat în interiorul AppModule în alte module. Totuși, primesc următoarea eroare:

"Excepție nepreluată (în promisiune): Eroare: Erori de analiză a șablonului:"

'contacts-box' nu este un element cunoscut:

  1. Dacă 'contacts-box' este un component Angular, atunci verifică dacă face parte din acest modul.
  2. Dacă 'contacts-box' este un Web Component, atunci adaugă 'CUSTOM_ELEMENTS_SCHEMA' la 'schemas' din '@NgModule' al acestui component pentru a suprima acest mesaj.

Structura proiectului meu este destul de simplă:

Îmi păstrez paginile în directorul pages, unde fiecare pagină este păstrată într-un modul diferit (de exemplu, modulul customers) și fiecare modul are mai multe componente (cum ar fi customers-list-component, customers-add-component și așa mai departe). Vreau să folosesc ContactBoxComponent-ul meu în interiorul acelor componente (de exemplu, în interiorul customers-add-component).

După cum puteți vedea, am creat componenta contacts-box în interiorul directorului widgets, deci este practic în interiorul AppModule. Am adăugat importul ContactBoxComponent în app.module.ts și l-am pus în lista de declarații a AppModule. Nu a funcționat, așa că am căutat problema mea pe Google și am adăugat ContactBoxComponent și în lista de exporturi. N-a ajutat. Am încercat, de asemenea, să pun ContactBoxComponent în CustomersAddComponent și apoi în altul (dintr-un modul diferit), dar am primit o eroare care spunea că există multiple declarații.

Ce îmi lipsește?

Răspuns #1

Aceștia sunt cei 5 pași pe care îi urmez atunci când primesc o astfel de eroare.

  • Ești sigur că numele este corect? (Verifică și selectorul definit în componentă)
  • Declară componenta într-un modul?
  • Dacă se află într-un alt modul, exportați componenta?
  • Dacă se află într-un alt modul, importă acel modul?
  • Reporniți CLI-ul?

Când apare eroarea în timpul testării unitare, asigură-te că ai declarat componenta sau ai importat modulul în TestBed.configureTestingModule

Am încercat, de asemenea, să pun ContactBoxComponent în CustomersAddComponent și apoi în altul (dintr-un modul diferit), dar am primit o eroare care spunea că există mai multe declarații.

Nu poți declara un component de două ori. Ar trebui să declari și să exporți componentul într-un modul nou separat. Apoi, ar trebui să imporți acest modul nou în fiecare modul în care vrei să folosești componentul.

Este greu de spus când ar trebui să creezi un modul nou și când nu. De obicei, creez un modul nou pentru fiecare componentă pe care o reutilizez. Când am componente pe care le folosesc aproape peste tot, le pun într-un singur modul. Când am o componentă pe care nu o reutilizez, nu voi crea un modul separat până nu am nevoie de ea în altă parte.

Deși ar putea fi tentant să pui toate componentele într-un singur modul, acest lucru este rău pentru performanță. În timpul dezvoltării, un modul trebuie recompilat de fiecare dată când se fac modificări. Cu cât modulul este mai mare (mai multe componente), cu atât durează mai mult. A face o mică modificare într-un modul mare ia mai mult timp decât a face o mică modificare într-un modul mic.

EDIT pentru v15

Angular 15 a introdus așa-numitele componente „Standalone”. Aceste componente NU trebuie să fie declarate într-un modul.

@Component({
  selector: 'app-hello',
  standalone: true, <------ NOTE THIS
  template: 'hello world',
})
export class StandaloneComponent {}

Folosirea unui component independent într-un component de modul:

@NgModule({
  imports: [
    CommonModule,
    StandaloneComponent
  ],
  declarations: [ModuleComponent],
  exports: [ModuleComponent],
})
export class ExampleModule {}

Folosirea unui component de modul într-un component independent:

@Component({
  selector: 'app-hello',
  standalone: true,
  template: 'hello world <module-component></module-component>',
  imports: [ExampleModule]
})
export class StandaloneComponent {}

Răspunsul #2

Am avut o problemă similară. S-a dovedit că ng generate component (folosind versiunea 7.1.4 a CLI) adaugă o declarație pentru componenta copil în AppModule, dar nu și în modulul TestBed care o emulează.

Exemplul de aplicație „Tour of Heroes” conține un HeroesComponent cu selectorul app-heroes. Aplicația a rulat bine atunci când a fost servită, dar ng test a produs acest mesaj de eroare: 'app-heroes' nu este un element cunoscut. Adăugarea manuală a HeroesComponent în declarațiile din configureTestingModule (în app.component.spec.ts) elimină această eroare.

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();
  });
}

Răspunsul #3

Tocmai am avut exact aceeași problemă. Înainte de a încerca unele dintre soluțiile postate aici, s-ar putea să vrei să verifici dacă componenta chiar nu funcționează. Pentru mine, eroarea era afișată în IDE-ul meu (WebStorm), dar s-a dovedit că codul funcționa perfect când l-am rulat în browser.

După ce am închis terminalul (care rula ng serve) și am repornit IDE-ul meu, mesajul a încetat să mai apară.

Răspuns #4

Multe răspunsuri/comentarii menționează componente definite în alte module, sau că trebuie să imporți/declari componenta (pe care vrei să o folosești într-o altă componentă) în modulul său/acelui modul care o conține.

Dar în cazul simplu în care vrei să folosești componenta A din componenta B atunci când ambele sunt definite în același modul, trebuie să declari ambele componente în modulul care le conține pentru ca B să vadă A, și nu doar A.

Adică în my-module.module.ts

import { AComponent } from "./A/A.component";
import { BComponent } from "./B/B.component";

@NgModule({
  declarations: [
    AComponent,   // This is the one that we naturally think of adding ..
    BComponent,   // .. but forget this one and you get a "**'AComponent'** 
                  // is not a known element" error.
  ],
})