Il 'componente' angolare 2 non è un elemento noto


135

Sto cercando di utilizzare un componente creato all'interno dell'AppModule in altri moduli. Ottengo il seguente errore:

"Uncaught (promessa): errore: errori di analisi del modello:

La "scatola dei contatti" non è un elemento noto:

  1. Se la "scatola dei contatti" è un componente angolare, verificare che faccia parte di questo modulo.
  2. Se "contatti-box" è un componente Web, aggiungere "CUSTOM_ELEMENTS_SCHEMA" a "@ NgModule.schemas" di questo componente per eliminare questo messaggio.

La struttura del mio progetto è abbastanza semplice: Struttura complessiva del progetto

Tengo le mie pagine nella directory delle pagine, in cui ogni pagina è conservata in un modulo diverso (ad esempio modulo clienti) e ogni modulo ha più componenti (come componenti-elenco-clienti, componente-aggiunta-clienti e così via). Voglio usare il mio ContactBoxComponent all'interno di quei componenti (quindi all'interno di clienti-aggiungi-componente per esempio).

Come puoi vedere, ho creato il componente box contatti nella directory dei widget, quindi è fondamentalmente all'interno dell'AppModule. Ho aggiunto l'importazione ContactBoxComponent a app.module.ts e l'ho inserito nell'elenco delle dichiarazioni di AppModule. Non ha funzionato, quindi ho cercato su Google il mio problema e ho aggiunto anche ContactBoxComponent all'elenco di esportazione. Non ha aiutato Ho anche provato a inserire ContactBoxComponent in ClientiAddComponent e poi in un altro (da un modulo diverso) ma ho ricevuto un errore dicendo che ci sono più dichiarazioni.

Cosa mi sto perdendo?


La struttura delle cartelle non è semplice. È confusionario. Suggerirei di seguire la Guida allo stile angolare (collegamento non fornito in b / c che cambiano) e utilizzare i suggerimenti per la struttura delle cartelle, quindi assicurarsi di utilizzare correttamente i moduli. Questo è ciò che significa. A un certo punto non stai esportando o dichiarando il tuo componente in un modulo ingerito dall'app.
Joshua Michael Wagoner,

Risposte:


277

Questi sono i 5 passaggi che eseguo quando ho riscontrato un tale errore.

  • Sei sicuro che il nome sia corretto? (controlla anche il selettore definito nel componente)
  • Dichiarare il componente in un modulo?
  • Se si trova in un altro modulo, esportare il componente?
  • Se si trova in un altro modulo, importare quel modulo?
  • Riavvia il cli?

Ho anche provato a inserire ContactBoxComponent in ClientiAddComponent e poi in un altro (da un modulo diverso) ma ho ricevuto un errore dicendo che ci sono più dichiarazioni.

Non è possibile dichiarare un componente due volte. È necessario dichiarare ed esportare il componente in un nuovo modulo separato. Successivamente è necessario importare questo nuovo modulo in ogni modulo che si desidera utilizzare il componente.

È difficile dire quando dovresti creare un nuovo modulo e quando non dovresti. Di solito creo un nuovo modulo per ogni componente che riutilizzo. Quando ho alcuni componenti che uso quasi ovunque li inserisco in un singolo modulo. Quando ho un componente che non riutilizzo, non creerò un modulo separato fino a quando non ne avrò bisogno altrove.

Anche se potrebbe essere allettante mettere tutti i componenti in un singolo modulo, questo è negativo per le prestazioni. Durante lo sviluppo, un modulo deve ricompilarsi ogni volta che vengono apportate modifiche. Più grande è il modulo (più componenti) più tempo ci vorrà. Fare una piccola modifica a un modulo grande richiede più tempo rispetto a una piccola modifica in un modulo piccolo.


6
I tuoi passi non mi hanno aiutato, ma forse è perché sono abbastanza nuovo in Angular 2, quindi risponderò a loro e forse troveremo la soluzione insieme. Sono sicuro che il nome sia corretto, ho dichiarato il componente in AppModule, ho esportato il componente in AppModule e riavviato il cli. Ho anche provato a importare AppModule nel mio Componente clienti addizionale ma mi è risultato un errore: Dimensione massima dello stack di chiamate superata (immagino che non importiamo AppModule in Angular 2).
Aranha,

7
È necessario dichiarare ed esportare il componente in un modulo separato, non in AppModule. Successivamente è necessario importare questo nuovo modulo in ogni modulo che si desidera utilizzare per il componente.
Robin Dijkhof,

2
Ok, ho capito adesso. L'unica domanda è: quando importerò il modulo appena creato (diciamo WidgetsModule), questo caricherà tutti i componenti dichiarati all'interno, giusto? Questo è un po 'sovraccarico ma forse sto fraintendendo qualcosa. Ovviamente potrei creare ContactsBoxModule ma è molto simile a un piccolo componente. Qualche suggerimento?
Aranha,

5
È giusto. Ed è difficile dire quando dovresti creare un nuovo modulo e quando non dovresti. Di solito creo un nuovo modulo per ogni componente che riutilizzo. Quando ho alcuni componenti che uso quasi ovunque li inserisco in un singolo modulo. Quando ho un componente che non riutilizzo, non creerò un modulo separato finché non ne avrò bisogno altrove.
Robin Dijkhof,

2
"Se si trova in un altro modulo, esportare il componente?" Ha funzionato per me!
Steven,

25

Ho avuto un problema simile. Si è scoperto che ng generate component(utilizzando la CLI versione 7.1.4) aggiunge una dichiarazione per il componente figlio ad AppModule, ma non al modulo TestBed che lo emula.

L'app di esempio "Tour of Heroes" contiene un HeroesComponentselettore app-heroes. Il funzionato benissimo app quando servito, ma ng testprodotto questo messaggio di errore: 'app-heroes' is not a known element. L'aggiunta HeroesComponentmanuale alle dichiarazioni tra configureTestingModule(in app.component.spec.ts) elimina questo errore.

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

Questo era il mio problema - ho dimenticato di aggiungere l'importazione nel file di test.
Sellorio,

17

Ho avuto esattamente lo stesso problema. Prima di provare alcune delle soluzioni pubblicate qui, potresti voler verificare se il componente non funziona davvero . Per me, l'errore è stato mostrato nel mio IDE (WebStorm), ma si è scoperto che il codice ha funzionato perfettamente quando l'ho eseguito nel browser.

Dopo aver spento il terminale (che stava eseguendo ng serve) e riavviato il mio IDE, il messaggio ha smesso di apparire.


Il problema è specifico dell'ide. Ho lo stesso problema con webstorm. Webstorm non è informato delle modifiche apportate con angular-cli, quindi è necessario riavviare l'IDE per "vedere" eventuali nuovi componenti!
skiabox

2
Ho lo stesso problema con VS Code ma con Ionic 2. In una pagina funziona. In un componente c'è l'errore ion- * non è un elemento noto . Ho provato il tuo suggerimento di interrompere il servizio ionico e ho riavviato l'IDE, ma non funziona nulla. Conosci un'altra soluzione per questo? A proposito: il codice funziona comunque.
Sebastian Ortmann,

Ha avuto lo stesso problema con VSCode. Dopo aver riavviato l'editor, il messaggio è andato via.
quicklikerabbit il


1

Nel mio caso, la mia app aveva più livelli di moduli, quindi il modulo che stavo cercando di importare doveva essere aggiunto al genitore del modulo che lo utilizzava effettivamente pages.module.ts, invece di app.module.ts.


0

Ho avuto lo stesso problema, e stava accadendo a causa del diverso modulo di funzionalità incluso questo componente per errore. Rimosso dall'altra funzione, ha funzionato!


0

Il problema nel mio caso mancava la dichiarazione del componente nel modulo, ma anche dopo aver aggiunto la dichiarazione l'errore è persistito. Ho dovuto arrestare il server e ricostruire l'intero progetto in VS Code affinché l'errore scompaia.


0

Questo quadro contorto mi sta facendo impazzire. Dato che hai definito il componente personalizzato nel modello di un'altra parte del modulo SAME, non è necessario utilizzare le esportazioni nel modulo (ad es. App.module.ts). Devi semplicemente specificare la dichiarazione nella direttiva @NgModule del suddetto modulo:

// app.module.ts

import { JsonInputComponent } from './json-input/json-input.component';

@NgModule({
  declarations: [
    AppComponent,
    JsonInputComponent
  ],
  ...

NON è necessario importare JsonInputComponent(in questo esempio) in AppComponent(in questo esempio) per utilizzare il JsonInputComponentcomponente personalizzato nel AppComponentmodello. Devi semplicemente aggiungere il prefisso al componente personalizzato con il nome del modulo di cui sono stati definiti entrambi i componenti (ad es. App):

<form [formGroup]="reactiveForm">
  <app-json-input formControlName="result"></app-json-input>
</form>

Nota app-json-input non json-input!

Demo qui: https://github.com/lovefamilychildrenhappiness/AngularCustomComponentValidation


0

Sto iniziando Angular e nel mio caso, il problema era che non avevo salvato il file dopo aver aggiunto l'istruzione 'import'.


0

Moduli di route (questa non è stata vista come una risposta)

Primo controllo: se hai dichiarato ed esportato il componente all'interno del suo modulo, importato il modulo in cui si desidera utilizzarlo e denominato correttamente il componente all'interno dell'HTML.

Altrimenti, è possibile che manchi un modulo all'interno del modulo di routing:
quando si dispone di un modulo di routing con una route che instrada a un componente da un altro modulo, è importante importare quel modulo all'interno di quel modulo di route. In caso contrario, l'angolare CLI mostrerà l'errore: component is not a known element.

Per esempio

1) Avere la seguente struttura del progetto:

├───core
   └───sidebar
           sidebar.component.ts
           sidebar.module.ts

└───todos
       todos-routing.module.ts
       todos.module.ts
    
    └───pages
            edit-todo.component.ts
            edit-todo.module.ts

2) All'interno todos-routing.module.tshai un percorso per edit.todo.component.ts(senza importare il suo modulo):

  {
    path: 'edit-todo/:todoId',
    component: EditTodoComponent,
  },

Il percorso funzionerà perfettamente! Tuttavia durante l'importazione del sidebar.module.tsdentro la edit-todo.module.tssi otterrà un errore: app-sidebar is not a known element.

Correzione: poiché hai aggiunto un percorso al edit-todo.component.tspassaggio 2, dovrai aggiungerlo edit-todo.module.tscome importazione, dopodiché il componente della barra laterale importato funzionerà!


0

Stavo affrontando lo stesso problema. Nel mio caso ho dimenticato di dichiarare il componente Parent in app.module.ts

Ad esempio, se si utilizza il <app-datapicker>selettore nel ToDayComponentmodello, è necessario dichiarare entrambi ToDayComponente DatepickerComponentin app.module.ts


0

Presumibilmente hai un componente:

prodotto-list.component.ts:

import { Component } from '@angular/core';
    
    @Component({
        selector: 'pm-products',  
        templateUrl: './product-list.component.html'
    })
    
    
    export class ProductListComponent {
      pageTitle: string = 'product list';
    }

E ottieni questo errore:

ERRORE in src / app / app.component.ts: 6: 3 - errore NG8001: "pm-products" non è un elemento noto:

  1. Se "pm-products" è un componente angolare, verificare che faccia parte di questo modulo.

app.component.ts:

import { Component } from "@angular/core";
@Component({
  selector: 'pm-root', // 'pm-root'
  template: `
  <div><h1>{{pageTitle}}</h1>
  <pm-products></pm-products> // not a known element ?
  </div>
  `
})
export class AppComponent {
  pageTitle: string = 'Acme Product Management';
}

Assicurati di importare il componente:

app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

// --> add this import (you can click on the light bulb in the squiggly line in VS Code)
import { ProductListComponent } from './products/product-list.component'; 

@NgModule({
  declarations: [
    AppComponent,
    ProductListComponent // --> Add this line here

  ],
  imports: [
    BrowserModule
  ],
  bootstrap: [AppComponent],


})
export class AppModule { }

0

Questa domanda può sembrare vecchia e strana, ma quando stavo provando a caricare un modulo (caricamento lento) e ottenendo lo stesso errore, mi sono reso conto che mancava una clausola di esportazione per il componente spedito come parte di un modulo più grande.

Questo link Angular.io spiega perché : componenti / servizi all'interno di un modulo, rimane privato (o protetto) per impostazione predefinita. Per renderli pubblici, devi esportarli.

Espandendo la risposta di @Robin Djikof con l' esempio di codice @ live-love , questo è ciò che tecnicamente mancava nel mio caso (Angular 8):

@NgModule({
  declarations: [
    SomeOtherComponent,
    ProductListComponent
  ],
  imports: [
    DependantModule
  ],
  exports: [ProductListComponent] 
  //<- This line makes ProductListComponent available outside the module, 
  //while keeping SomeOtherComponent private to the module
})
export class SomeLargeModule { }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.