„Komponent” kątowy 2 nie jest znanym elementem

134

Próbuję użyć komponentu, który utworzyłem wewnątrz AppModule w innych modułach. Pojawia się jednak następujący błąd:

„Nieprzechwycony (obiecany): Błąd: błędy analizy szablonu:

„skrzynka kontaktów” nie jest znanym elementem:

  1. Jeśli „skrzynka kontaktów” jest komponentem kątowym, sprawdź, czy jest częścią tego modułu.
  2. Jeśli „contact-box” jest składnikiem sieciowym, dodaj „CUSTOM_ELEMENTS_SCHEMA” do „@ NgModule.schemas” tego komponentu, aby ukryć ten komunikat.

Struktura mojego projektu jest dość prosta: Ogólna struktura projektu

Trzymam swoje strony w katalogu stron, gdzie każda strona jest przechowywana w innym module (np. Module klientów), a każdy moduł ma wiele komponentów (takich jak komponent listy klientów, komponent dodawania klientów i tak dalej). Chcę używać mojego komponentu ContactBoxComponent wewnątrz tych komponentów (na przykład wewnątrz komponentu dodawania klientów).

Jak widać, utworzyłem komponent skrzynki kontaktów w katalogu widżetów, więc jest w zasadzie wewnątrz AppModule. Dodałem import ContactBoxComponent do app.module.ts i umieściłem go na liście deklaracji AppModule. To nie zadziałało, więc wygooglowałem mój problem i dodałem ContactBoxComponent również do listy eksportu. Nie pomogło. Próbowałem też umieścić ContactBoxComponent w CustomersAddComponent, a następnie w innym (z innego modułu), ale pojawił się błąd informujący, że jest wiele deklaracji.

czego mi brakuje?

Aranha
źródło
Twoja struktura folderów nie jest prosta. To zagmatwane. Proponuję postępować zgodnie z przewodnikiem po Angular Style (link nie jest podany, ponieważ zmieniają się) i skorzystać z sugestii dotyczących struktury folderów, a następnie upewnić się, że używasz modułów poprawnie. To właśnie to oznacza. W pewnym momencie nie eksportujesz ani nie deklarujesz swojego komponentu w module pozyskanym przez aplikację.
Joshua Michael Wagoner

Odpowiedzi:

277

Oto 5 kroków, które wykonuję, gdy mam taki błąd.

  • Czy na pewno nazwa jest poprawna? (sprawdź także selektor zdefiniowany w komponencie)
  • Zadeklarować komponent w module?
  • Jeśli jest w innym module, wyeksportować komponent?
  • Jeśli jest w innym module, zaimportować ten moduł?
  • Zrestartować CLI?

Próbowałem też umieścić ContactBoxComponent w CustomersAddComponent, a następnie w innym (z innego modułu), ale pojawił się błąd informujący, że jest wiele deklaracji.

Nie możesz dwukrotnie zadeklarować komponentu. Powinieneś zadeklarować i wyeksportować swój komponent w nowym oddzielnym module. Następnie powinieneś zaimportować ten nowy moduł w każdym module, którego chcesz użyć.

Trudno powiedzieć, kiedy należy stworzyć nowy moduł, a kiedy nie. Zwykle tworzę nowy moduł dla każdego komponentu, którego ponownie używam. Kiedy mam jakieś komponenty, których używam prawie wszędzie, umieszczam je w jednym module. Kiedy mam komponent, którego nie używam ponownie, nie utworzę oddzielnego modułu, dopóki nie będę go potrzebował gdzie indziej.

Chociaż może być kuszące umieszczenie wszystkich komponentów w jednym module, jest to niekorzystne dla wydajności. Podczas programowania moduł musi być ponownie kompilowany za każdym razem, gdy wprowadzane są zmiany. Im większy moduł (więcej komponentów), tym więcej czasu zajmuje. Dokonanie małej zmiany w dużym module zajmuje więcej czasu niż dokonanie małej zmiany w małym module.

Robin Dijkhof
źródło
6
Twoje kroki nie pomogły mi, ale może dlatego, że jestem całkiem nowy w Angular 2, więc odpowiem na nie i być może wspólnie wymyślimy rozwiązanie. Jestem pewien, że nazwa jest poprawna, zadeklarowałem komponent w AppModule, wyeksportowałem komponent w AppModule i zrestartowałem CLI. Próbowałem również zaimportować AppModule w moim CustomersAddComponent, ale skutkowało to błędem: Przekroczono maksymalny rozmiar stosu wywołań (chyba nie importujemy AppModule w Angular 2).
Aranha
7
Powinieneś zadeklarować i wyeksportować swój komponent w oddzielnym module, a nie w AppModule. Następnie powinieneś zaimportować ten nowy moduł do dowolnego modułu, którego chcesz użyć.
Robin Dijkhof
2
OK, teraz rozumiem. Jedyne pytanie brzmi: kiedy importuję nowo utworzony moduł (powiedzmy WidgetsModule), załadowałby on aaaaa wszystkie zadeklarowane w nim komponenty, prawda? To trochę narzutów, ale może coś nie rozumiem. Mógłbym oczywiście stworzyć ContactsBoxModule, ale to dużo jak na jeden mały komponent. Jakieś wskazówki?
Aranha
5
Tak jest. Trudno powiedzieć, kiedy należy stworzyć nowy moduł, a kiedy nie. Zwykle tworzę nowy moduł dla każdego komponentu, którego ponownie używam. Kiedy mam jakieś komponenty, których używam prawie wszędzie, umieszczam je w jednym module. Kiedy mam komponent, którego nie używam ponownie, nie utworzę oddzielnego modułu, dopóki nie będę go potrzebował gdzie indziej.
Robin Dijkhof
2
„Jeśli jest w innym module, czy wyeksportować komponent?” Pracował dla mnie!
Steven
25

Miałem podobny problem. Okazało się, że ng generate component(używając CLI w wersji 7.1.4) dodaje deklarację dla komponentu potomnego do AppModule, ale nie do modułu TestBed, który go emuluje.

Przykładowa aplikacja „Tour of Heroes” zawiera HeroesComponentselektor with app-heroes. Aplikacja ran porządku kiedy służył, ale ng testprodukowane ten komunikat o błędzie: 'app-heroes' is not a known element. Dodanie HeroesComponentręcznie do deklaracji w configureTestingModule(in app.component.spec.ts) eliminuje ten błąd.

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
źródło
To był mój problem - zapomniałem dodać Import w pliku testowym.
Sellorio
17

Właśnie miałem dokładnie ten sam problem. Przed wypróbowaniem niektórych z zamieszczonych tutaj rozwiązań możesz sprawdzić, czy komponent naprawdę nie działa. U mnie błąd pojawił się w moim IDE (WebStorm), ale okazało się, że kod działał idealnie po uruchomieniu go w przeglądarce.

Po zamknięciu terminala (na którym działał ng serv) i ponownym uruchomieniu IDE, komunikat przestał się pojawiać.

harryvederci
źródło
Problem jest specyficzny dla jaza. Mam ten sam problem z burzą internetową. Webstorm nie jest informowany o zmianach dokonanych za pomocą angular-cli, więc musisz ponownie uruchomić IDE, aby „zobaczyło” nowe komponenty!
skiabox,
2
Mam ten sam problem z VS Code, ale z Ionic 2. Na stronie to działa. W komponencie występuje błąd jon- * nie jest znanym elementem . Wypróbowałem twoją sugestię, aby zatrzymać obsługę jonową i ponownie uruchomić IDE, ale nic nie działa. Czy znasz inne rozwiązanie tego problemu? Swoją drogą - kod i tak działa.
Sebastian Ortmann,
Miałem ten sam problem z VSCode. Po ponownym uruchomieniu edytora komunikat zniknął.
quicklikerabbit
1

W moim przypadku moja aplikacja miała wiele warstw modułów, więc moduł, który próbowałem zaimportować, musiał zostać dodany do modułu nadrzędnego modułu, który faktycznie go używał pages.module.ts, zamiast app.module.ts.

Kof
źródło
0

Otrzymałem ten sam problem i działo się to, ponieważ inny moduł funkcji przez pomyłkę zawierał ten komponent. Po usunięciu go z innej funkcji działało!

Vladimir Mitic
źródło
0

Problemem w moim przypadku był brak deklaracji komponentu w module, ale nawet po dodaniu deklaracji błąd nie ustąpił. Musiałem zatrzymać serwer i odbudować cały projekt w kodzie VS, aby błąd zniknął.

Eternal21
źródło
0

Te zawiłe ramy doprowadzają mnie do szału. Biorąc pod uwagę, że zdefiniowałeś komponent niestandardowy w szablonie innej części komponentu modułu SAMEJ, nie musisz używać eksportów w module (np. App.module.ts). Wystarczy określić deklarację w dyrektywie @NgModule wspomnianego modułu:

// app.module.ts

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

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

NIE musisz importować JsonInputComponent(w tym przykładzie) do AppComponent(w tym przykładzie), aby użyć JsonInputComponentkomponentu niestandardowego w AppComponentszablonie. Wystarczy poprzedzić komponent niestandardowy nazwą modułu, którego oba komponenty zostały zdefiniowane (np. Aplikacja):

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

Zwróć uwagę, że app-json-input nie json-input!

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

Donato
źródło
0

Rozpoczynam Angular iw moim przypadku problem polegał na tym, że nie zapisałem pliku po dodaniu instrukcji „import”.

user637563
źródło
0

Moduły tras (nie widziałem tego jako odpowiedzi)

Pierwsza kontrola: jeśli zadeklarowałeś - i wyeksportowałeś komponent wewnątrz jego modułu, zaimportuj moduł, w którym chcesz go użyć i poprawnie nazwij komponent w HTML.

W przeciwnym razie możesz przegapić moduł wewnątrz modułu routingu:
jeśli masz moduł routingu z trasą, która kieruje do komponentu z innego modułu, ważne jest, aby zaimportować ten moduł w ramach tego modułu trasy. W przeciwnym razie kątowe CLI pokaże błąd: component is not a known element.

Na przykład

1) Posiadające następującą strukturę projektu:

├───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) Wewnątrz todos-routing.module.tsmasz trasę do edit.todo.component.ts(bez importowania jego modułu):

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

Trasa będzie działać dobrze! Jednak podczas importowania sidebar.module.tswewnątrz edit-todo.module.tsdostaniesz błąd: app-sidebar is not a known element.

Poprawka: Ponieważ dodałeś trasę do edit-todo.component.tskroku 2, będziesz musiał dodać edit-todo.module.tsjako import, po czym importowany komponent paska bocznego będzie działał!

Brampage
źródło
0

Miałem ten sam problem. W moim przypadku zapomniałem zadeklarować komponent Parent w app.module.ts

Jako przykład, jeśli używasz <app-datapicker>selektor w ToDayComponentszablonie, należy zadeklarować zarówno ToDayComponenti DatepickerComponentw app.module.ts

Rajitha Kithuldeniya
źródło
0

Podobno masz komponent:

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

Otrzymujesz ten błąd:

BŁĄD w src / app / app.component.ts: 6: 3 - błąd NG8001: „pm-products” nie jest znanym elementem:

  1. Jeśli „pm-products” jest komponentem Angular, sprawdź, czy jest częścią tego modułu.

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

Upewnij się, że importujesz komponent:

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 { }
miłość na żywo
źródło
0

To pytanie może wydawać się stare i dziwne, ale kiedy próbowałem załadować moduł (ładowanie leniwe) i otrzymałem ten sam błąd, zdałem sobie sprawę, że brakuje mi klauzuli eksportu dla komponentu, który został wysłany jako część większego modułu.

To łącze Angular.io wyjaśnia, dlaczego : Komponenty / usługi w module domyślnie pozostają prywatne (lub chronione). Aby je upublicznić, musisz je wyeksportować.

Rozwijając na odpowiedź @Robin Djikof jest z @ kodu live-miłosny próbki , to co zostało technicznie brakuje w moim przypadku (kątowa 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 { }
PO POŁUDNIU
źródło