Winkel 2 'Komponente' ist kein bekanntes Element

133

Ich versuche, eine Komponente, die ich im AppModule erstellt habe, in anderen Modulen zu verwenden. Ich erhalte jedoch den folgenden Fehler:

"Nicht gefangen (im Versprechen): Fehler: Fehler beim Analysieren der Vorlage:

'Kontaktbox' ist kein bekanntes Element:

  1. Wenn 'Kontaktbox' eine Winkelkomponente ist, überprüfen Sie, ob sie Teil dieses Moduls ist.
  2. Wenn 'contactes-box' eine Webkomponente ist, fügen Sie 'CUSTOM_ELEMENTS_SCHEMA' zu '@ NgModule.schemas' dieser Komponente hinzu, um diese Nachricht zu unterdrücken.

Meine Projektstruktur ist ganz einfach: Gesamtprojektstruktur

Ich behalte meine Seiten im Seitenverzeichnis, in dem jede Seite in einem anderen Modul (z. B. Kundenmodul) gespeichert ist und jedes Modul mehrere Komponenten enthält (z. B. Kundenlistenkomponente, Kundenadditionskomponente usw.). Ich möchte meine ContactBoxComponent in diesen Komponenten verwenden (z. B. in der Kunden-Add-Komponente).

Wie Sie sehen können, habe ich die Kontaktbox-Komponente im Widgets-Verzeichnis erstellt, sodass sie sich im Wesentlichen im AppModule befindet. Ich habe den Import von ContactBoxComponent zu app.module.ts hinzugefügt und ihn in die Deklarationsliste von AppModule eingefügt. Es hat nicht funktioniert, also habe ich mein Problem gegoogelt und ContactBoxComponent ebenfalls zur Exportliste hinzugefügt. Hat nicht geholfen. Ich habe auch versucht, ContactBoxComponent in CustomersAddComponent und dann in ein anderes (aus einem anderen Modul) einzufügen, aber es wurde eine Fehlermeldung angezeigt, dass mehrere Deklarationen vorhanden sind.

Was vermisse ich?

Aranha
quelle
Ihre Ordnerstruktur ist nicht einfach. Es ist verwirrend. Ich würde vorschlagen, dem Angular Style Guide zu folgen (Link nicht bereitgestellt, da sie sich ändern) und ihre Vorschläge zur Ordnerstruktur zu verwenden und dann sicherzustellen, dass Sie die Module korrekt verwenden. Das bedeutet das. Sie exportieren oder deklarieren Ihre Komponente nicht in einem Modul, das irgendwann von der App aufgenommen wurde.
Joshua Michael Waggoner

Antworten:

276

Dies sind die 5 Schritte, die ich durchführe, wenn ich einen solchen Fehler bekomme.

  • Sind Sie sicher, dass der Name korrekt ist? (Überprüfen Sie auch den in der Komponente definierten Selektor.)
  • Komponente in einem Modul deklarieren?
  • Wenn es sich in einem anderen Modul befindet, exportieren Sie die Komponente?
  • Wenn es sich in einem anderen Modul befindet, importieren Sie dieses Modul?
  • Cli neu starten?

Ich habe auch versucht, ContactBoxComponent in CustomersAddComponent und dann in ein anderes (aus einem anderen Modul) einzufügen, aber es wurde eine Fehlermeldung angezeigt, dass mehrere Deklarationen vorhanden sind.

Sie können eine Komponente nicht zweimal deklarieren. Sie sollten Ihre Komponente in einem neuen separaten Modul deklarieren und exportieren. Als nächstes sollten Sie dieses neue Modul in jedes Modul importieren, in dem Sie Ihre Komponente verwenden möchten.

Es ist schwer zu sagen, wann Sie ein neues Modul erstellen sollten und wann nicht. Normalerweise erstelle ich für jede wiederverwendete Komponente ein neues Modul. Wenn ich einige Komponenten habe, die ich fast überall verwende, füge ich sie in ein einziges Modul ein. Wenn ich eine Komponente habe, die ich nicht wiederverwenden kann, erstelle ich ein separates Modul, bis ich es woanders benötige.

Obwohl es verlockend sein könnte, alle Komponenten in einem einzigen Modul zusammenzufassen, ist dies schlecht für die Leistung. Während der Entwicklung muss ein Modul jedes Mal neu kompiliert werden, wenn Änderungen vorgenommen werden. Je größer das Modul (mehr Komponenten), desto länger dauert es. Das Vornehmen einer kleinen Änderung am großen Modul dauert länger als das Vornehmen einer kleinen Änderung an einem kleinen Modul.

Robin Dijkhof
quelle
6
Ihre Schritte haben mir nicht geholfen, aber vielleicht liegt es daran, dass ich in Angular 2 ziemlich neu bin, also werde ich sie beantworten und vielleicht werden wir gemeinsam die Lösung finden. Ich bin sicher, dass der Name korrekt ist. Ich habe die Komponente in AppModule deklariert, die Komponente in AppModule exportiert und die CLI neu gestartet. Ich habe auch versucht, AppModule in meine CustomersAddComponent zu importieren, aber es kam zu dem Fehler: Die maximale Größe des Aufrufstapels wurde überschritten (ich denke, wir importieren AppModule nicht in Angular 2).
Aranha
7
Sie sollten Ihre Komponente in einem separaten Modul deklarieren und exportieren, nicht in AppModule. Als nächstes sollten Sie dieses neue Modul in jedes Modul importieren, das Sie zur Verwendung Ihrer Komponente benötigen.
Robin Dijkhof
2
Okay, ich verstehe es jetzt. Die Frage ist nur: Wenn ich das neu erstellte Modul (z. B. WidgetsModule) importiere, werden aaaaa alle darin deklarierten Komponenten geladen, oder? Das ist etwas Aufwand, aber vielleicht verstehe ich etwas falsch. Ich könnte natürlich ContactsBoxModule erstellen, aber das ist viel wie für eine kleine Komponente. Irgendwelche Hinweise?
Aranha
5
Das ist richtig. Und es ist schwer zu sagen, wann Sie ein neues Modul erstellen sollten und wann nicht. Normalerweise erstelle ich für jede wiederverwendete Komponente ein neues Modul. Wenn ich einige Komponenten habe, die ich fast überall verwende, füge ich sie in ein einziges Modul ein. Wenn ich eine Komponente habe, die ich nicht wiederverwenden kann, erstelle ich ein separates Modul, bis ich es woanders benötige.
Robin Dijkhof
2
"Wenn es sich in einem anderen Modul befindet, exportieren Sie die Komponente?" Hat für mich gearbeitet!
Steven
25

Ich hatte ein ähnliches Problem. Es stellte sich heraus, dass ng generate component(unter Verwendung der CLI-Version 7.1.4) dem AppModule eine Deklaration für die untergeordnete Komponente hinzugefügt wird, nicht jedoch dem TestBed-Modul, das sie emuliert.

Die Beispiel-App "Tour of Heroes" enthält einen HeroesComponentWith-Selektor app-heroes. Die App lief beim Servieren einwandfrei, ng testerzeugte jedoch die folgende Fehlermeldung : 'app-heroes' is not a known element. Durch HeroesComponentmanuelles Hinzufügen der zu den Deklarationen in configureTestingModule(in app.component.spec.ts) wird dieser Fehler behoben.

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();
  });
}
Jan Hettich
quelle
Dies war mein Problem - ich habe vergessen, Import in Testdatei hinzuzufügen.
Sellorio
17

Ich hatte genau das gleiche Problem. Bevor Sie einige der hier veröffentlichten Lösungen ausprobieren, sollten Sie überprüfen, ob die Komponente wirklich nicht funktioniert. Für mich wurde der Fehler in meiner IDE (WebStorm) angezeigt, aber es stellte sich heraus, dass der Code perfekt funktionierte, als ich ihn im Browser ausführte.

Nachdem ich das Terminal heruntergefahren hatte (auf dem ng serve ausgeführt wurde) und meine IDE neu gestartet hatte, wurde die Meldung nicht mehr angezeigt.

harryvederci
quelle
Das Problem ist ideenspezifisch. Ich habe das gleiche Problem mit Webstorm. Webstorm wird nicht über Änderungen informiert, die mit angle-cli vorgenommen wurden. Sie müssen daher die IDE neu starten, damit neue Komponenten angezeigt werden.
Skiabox
2
Ich habe das gleiche Problem mit VS Code, aber mit Ionic 2. Auf einer Seite funktioniert es. In einer Komponente gibt es den Fehler ion- * ist kein bekanntes Element . Ich habe Ihren Vorschlag versucht, den ionischen Aufschlag zu stoppen , und die IDE neu gestartet, aber nichts funktioniert. Kennen Sie eine andere Lösung dafür? Übrigens - der Code funktioniert trotzdem.
Sebastian Ortmann
Hatte das gleiche Problem mit VSCode. Nach dem Neustart des Editors verschwand die Nachricht.
quicklikerabbit
1

In meinem Fall hatte meine App mehrere Modulebenen, sodass das Modul, das ich importieren wollte, dem übergeordneten Modul hinzugefügt werden musste, das es tatsächlich verwendet hat pages.module.ts, anstatt app.module.ts.

Kof
quelle
0

Ich habe das gleiche Problem und es passierte, weil verschiedene Funktionsmodule diese Komponente versehentlich enthalten haben. Wenn es von der anderen Funktion entfernt wurde, hat es funktioniert!

Vladimir Mitic
quelle
0

In meinem Fall fehlte die Komponentendeklaration im Modul, aber auch nach dem Hinzufügen der Deklaration blieb der Fehler bestehen. Ich hatte den Server gestoppt und das gesamte Projekt in VS Code neu erstellt, damit der Fehler behoben wurde.

Eternal21
quelle
0

Dieser verschlungene Rahmen macht mich verrückt. Da Sie die benutzerdefinierte Komponente in der Vorlage eines anderen Komponententeils des SAME-Moduls definiert haben, müssen Sie keine Exporte im Modul verwenden (z. B. app.module.ts). Sie müssen lediglich die Deklaration in der @ NgModule-Direktive des oben genannten Moduls angeben:

// app.module.ts

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

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

Sie müssen die JsonInputComponent(in diesem Beispiel) NICHT in AppComponent(in diesem Beispiel) importieren , um die JsonInputComponentbenutzerdefinierte Komponente in der AppComponentVorlage zu verwenden. Sie müssen der benutzerdefinierten Komponente lediglich den Modulnamen voranstellen, für den beide Komponenten definiert wurden (z. B. App):

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

Beachten Sie, dass App-JSON-Eingabe nicht JSON-Eingabe ist!

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

Donato
quelle
0

Ich beginne mit Angular und in meinem Fall bestand das Problem darin, dass ich die Datei nach dem Hinzufügen der Anweisung 'import' nicht gespeichert hatte.

user637563
quelle
0

Routenmodule (sah dies nicht als Antwort)

Überprüfen Sie zunächst: Wenn Sie die Komponente in ihrem Modul deklariert und exportiert haben, importieren Sie das Modul, in das Sie es verwenden möchten, und benennen Sie die Komponente im HTML korrekt.

Andernfalls könnte ein Modul in Ihrem Routing-Modul fehlen:
Wenn Sie ein Routing-Modul mit einer Route haben, die von einem anderen Modul zu einer Komponente weitergeleitet wird, ist es wichtig, dass Sie dieses Modul in dieses Routing-Modul importieren. Andernfalls zeigt die Angular CLI den Fehler an : component is not a known element.

Beispielsweise

1) Folgende Projektstruktur haben:

├───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) Innerhalb der haben todos-routing.module.tsSie eine Route zu edit.todo.component.ts(ohne das Modul zu importieren):

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

Die Route wird gut funktionieren! Beim Importieren der sidebar.module.tsInnenseite edit-todo.module.tswird jedoch eine Fehlermeldung angezeigt : app-sidebar is not a known element.

Fix: Da Sie edit-todo.component.tsin Schritt 2 eine Route hinzugefügt haben , müssen Sie diese edit-todo.module.tsals Import hinzufügen , danach funktioniert die importierte Seitenleisten-Komponente!

Brampage
quelle
0

Ich stand vor dem gleichen Problem. In meinem Fall habe ich vergessen, die übergeordnete Komponente in der Datei app.module.ts zu deklarieren

Wenn Sie beispielsweise den <app-datapicker>Selektor in der ToDayComponentVorlage verwenden, sollten Sie beide ToDayComponentund DatepickerComponentin der Datei app.module.ts deklarieren

Rajitha Kithuldeniya
quelle
0

Angeblich haben Sie eine Komponente:

product-list.component.ts:

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

Und Sie erhalten diesen Fehler:

FEHLER in src / app / app.component.ts: 6: 3 - Fehler NG8001: 'pm-products' ist kein bekanntes Element:

  1. Wenn 'pm-products' eine Angular-Komponente ist, überprüfen Sie, ob sie Teil dieses Moduls ist.

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';
}

Stellen Sie sicher, dass Sie die Komponente importieren:

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 { }
Live-Liebe
quelle
0

Diese Frage mag alt und seltsam erscheinen, aber als ich versuchte, ein Modul zu laden (verzögertes Laden) und denselben Fehler erhielt, stellte ich fest, dass mir eine Exportklausel für die Komponente fehlte , die als Teil eines größeren Moduls geliefert wurde.

Dieser Angular.io-Link erklärt, warum : Komponenten / Dienste innerhalb eines Moduls standardmäßig privat (oder geschützt) bleiben. Um sie öffentlich zu machen, müssen Sie sie exportieren.

In meinem Fall (Angular 8) fehlte die Antwort von @Robin Djikof mit dem @ live-love-Codebeispiel :

@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 { }
PM
quelle