'Komponen' sudut 2 bukanlah elemen yang diketahui

135

Saya mencoba menggunakan komponen yang saya buat di dalam AppModule di modul lain. Saya mendapatkan kesalahan berikut:

"Tidak tertangkap (berjanji): Kesalahan: Kesalahan parse templat:

'kontak-kotak' bukan elemen yang dikenal:

  1. Jika 'kontak-kotak' adalah komponen Angular, maka verifikasi bahwa itu adalah bagian dari modul ini.
  2. Jika 'kontak-kotak' adalah Komponen Web maka tambahkan 'CUSTOM_ELEMENTS_SCHEMA' ke '@ NgModule.schemas' dari komponen ini untuk menekan pesan ini.

Struktur proyek saya cukup sederhana: Struktur proyek secara keseluruhan

Saya menyimpan halaman saya di direktori halaman, di mana setiap halaman disimpan dalam modul yang berbeda (misalnya modul pelanggan) dan setiap modul memiliki banyak komponen (seperti komponen daftar pelanggan, komponen tambah pelanggan, dan sebagainya). Saya ingin menggunakan ContactBoxComponent saya di dalam komponen-komponen (jadi di dalam pelanggan-tambah-komponen misalnya).

Seperti yang Anda lihat, saya membuat komponen kontak-kotak di dalam direktori widget sehingga pada dasarnya di dalam AppModule. Saya menambahkan impor ContactBoxComponent ke app.module.ts dan memasukkannya ke dalam daftar deklarasi AppModule. Itu tidak berhasil jadi saya mencari masalah saya di Google dan menambahkan ContactBoxComponent ke daftar ekspor juga. Tidak membantu Saya juga mencoba meletakkan ContactBoxComponent di CustomersAddComponent dan kemudian di yang lain (dari modul yang berbeda) tapi saya mendapat kesalahan dengan mengatakan ada beberapa deklarasi.

Apa yang saya lewatkan?

Aranha
sumber
Struktur folder Anda tidak sederhana. Ini membingungkan. Saya akan menyarankan mengikuti Panduan Gaya Sudut (tautan tidak disediakan b / c mereka berubah) dan menggunakan saran struktur folder mereka dan kemudian pastikan bahwa Anda menggunakan modul dengan benar. Itu artinya ini. Anda entah tidak mengekspor atau mendeklarasikan komponen Anda dalam modul yang dicerna oleh aplikasi di beberapa titik.
Joshua Michael Wagoner

Jawaban:

277

Ini adalah 5 langkah yang saya lakukan ketika saya mendapat kesalahan seperti itu.

  • Apakah Anda yakin nama itu benar? (periksa juga pemilih yang ditentukan dalam komponen)
  • Deklarasikan komponen dalam modul?
  • Jika ada di modul lain, ekspor komponen?
  • Jika ada di modul lain, impor modul itu?
  • Mulai ulang cli?

Saya juga mencoba meletakkan ContactBoxComponent di CustomersAddComponent dan kemudian di yang lain (dari modul yang berbeda) tapi saya mendapat kesalahan dengan mengatakan ada beberapa deklarasi.

Anda tidak dapat mendeklarasikan komponen dua kali. Anda harus mendeklarasikan dan mengekspor komponen Anda dalam modul terpisah baru. Selanjutnya Anda harus mengimpor modul baru ini di setiap modul yang ingin Anda gunakan komponen Anda.

Sulit untuk mengatakan kapan Anda harus membuat modul baru dan kapan Anda seharusnya tidak. Saya biasanya membuat modul baru untuk setiap komponen yang saya gunakan kembali. Ketika saya memiliki beberapa komponen yang saya gunakan hampir di mana-mana saya meletakkannya dalam satu modul. Ketika saya memiliki komponen yang tidak saya gunakan kembali, saya tidak akan membuat modul terpisah sampai saya membutuhkannya di tempat lain.

Meskipun mungkin tergoda untuk menempatkan semua komponen Anda dalam satu modul, ini buruk untuk kinerja. Saat mengembangkan, modul harus mengkompilasi ulang setiap kali perubahan dilakukan. Semakin besar modul (lebih banyak komponen) semakin banyak waktu yang dibutuhkan. Membuat perubahan kecil ke modul besar membutuhkan lebih banyak waktu daripada membuat perubahan kecil dalam modul kecil.

Robin Dijkhof
sumber
6
Langkah Anda tidak membantu saya tapi mungkin itu karena saya cukup baru untuk Angular 2, jadi saya akan menjawabnya dan mungkin kita akan mencari solusinya bersama-sama. Saya yakin namanya benar, saya mendeklarasikan komponen di AppModule, saya mengekspor komponen di AppModule dan memulai kembali cli. Saya juga mencoba mengimpor AppModule di CustomerAddComponent saya tetapi mengakibatkan Kesalahan: Ukuran tumpukan panggilan maksimum terlampaui (saya kira kita tidak mengimpor AppModule dalam Angular 2).
Aranha
7
Anda harus mendeklarasikan dan mengekspor komponen Anda dalam modul terpisah, Bukan di AppModule. Selanjutnya Anda harus mengimpor modul baru ini di setiap modul yang ingin Anda gunakan komponen Anda.
Robin Dijkhof
2
Oke, saya mengerti sekarang. Satu-satunya pertanyaan adalah: ketika saya mengimpor modul yang baru dibuat (katakanlah WidgetsModule) itu akan memuat aaaaaall semua komponen yang dideklarasikan di dalamnya, kan? Itu beberapa overhead tetapi mungkin saya salah paham sesuatu. Tentu saja saya bisa membuat ContactsBoxModule tapi itu banyak untuk satu komponen kecil. Ada petunjuk?
Aranha
5
Itu benar. Dan sulit untuk mengatakan kapan Anda harus membuat modul baru dan kapan Anda seharusnya tidak. Saya biasanya membuat modul baru untuk setiap komponen yang saya gunakan kembali. Ketika saya memiliki beberapa komponen yang saya gunakan hampir di mana-mana saya meletakkannya dalam satu modul. Ketika saya memiliki komponen yang tidak saya gunakan kembali, saya tidak akan membuat modul terpisah sampai saya membutuhkannya di tempat lain.
Robin Dijkhof
2
"Jika ada di modul lain, ekspor komponen?" Bekerja untukku!
Steven
25

Saya punya masalah serupa. Ternyata ng generate component(menggunakan CLI versi 7.1.4) menambahkan deklarasi untuk komponen turunan ke AppModule, tetapi tidak ke modul TestBed yang mengemulasi itu.

Aplikasi sampel "Tour of Heroes" berisi HeroesComponentpemilih dengan app-heroes. Aplikasi berlari dengan baik ketika menjabat, tapi ng testdiproduksi pesan kesalahan ini: 'app-heroes' is not a known element. Menambahkan HeroesComponentsecara manual ke deklarasi di configureTestingModule(in app.component.spec.ts) menghilangkan kesalahan ini.

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
sumber
Ini masalah saya - lupa menambahkan Impor dalam file uji.
Sellorio
17

Saya baru saja mengalami masalah yang sama persis. Sebelum mencoba beberapa solusi yang diposting di sini, Anda mungkin ingin memeriksa apakah komponennya benar - benar tidak berfungsi. Bagi saya, kesalahan ditampilkan di IDE saya (WebStorm), tetapi ternyata kode tersebut bekerja dengan sempurna ketika saya menjalankannya di browser.

Setelah saya mematikan terminal (yang menjalankan ng servis) dan me-restart IDE saya, pesan berhenti muncul.

harryvederci
sumber
Masalahnya adalah ide-spesifik. Saya memiliki masalah yang sama dengan webstorm. Webstorm tidak diinformasikan untuk perubahan yang dilakukan dengan angular-cli sehingga Anda harus memulai ulang IDE untuk membuatnya 'melihat' komponen baru!
skiabox
2
Saya memiliki masalah yang sama dengan VS Code tetapi dengan Ionic 2. Pada halaman berfungsi. Dalam komponen ada kesalahan ion- * bukan elemen yang dikenal . Saya sudah mencoba saran Anda untuk menghentikan layanan ion dan memulai kembali IDE, tetapi tidak ada yang berhasil. Apakah Anda tahu solusi lain untuk ini? By the way - kode itu tetap bekerja.
Sebastian Ortmann
Punya masalah yang sama dengan VSCode. Setelah restart editor pesannya hilang.
quicklikerabbit
1

Dalam kasus saya, aplikasi saya memiliki beberapa lapisan modul, jadi modul yang saya coba impor harus ditambahkan ke induk modul yang benar-benar menggunakannya pages.module.ts, bukan app.module.ts.

Kof
sumber
0

Saya mendapat masalah yang sama, dan itu terjadi karena modul fitur yang berbeda termasuk komponen ini secara tidak sengaja. Ketika dihapus dari fitur lain, itu berhasil!

Vladimir Mitic
sumber
0

Masalah dalam kasus saya adalah tidak adanya deklarasi komponen dalam modul, tetapi bahkan setelah menambahkan deklarasi kesalahan tetap ada. Saya telah menghentikan server dan membangun kembali seluruh proyek dalam Kode VS untuk kesalahan untuk pergi.

Eternal21
sumber
0

Kerangka berbelit-belit ini membuatku gila. Mengingat Anda mendefinisikan komponen khusus dalam templat bagian komponen lain dari modul SAMA, maka Anda tidak perlu menggunakan ekspor dalam modul (mis. App.module.ts). Anda hanya perlu menentukan deklarasi di direktif @NgModule dari modul yang disebutkan di atas:

// app.module.ts

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

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

Anda TIDAK perlu mengimpor JsonInputComponent(dalam contoh ini) ke AppComponent(dalam contoh ini) untuk menggunakan JsonInputComponentkomponen khusus dalam AppComponenttemplat. Anda hanya perlu awalan komponen khusus dengan nama modul yang kedua komponen telah didefinisikan (misalnya aplikasi):

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

Perhatikan app-json-input bukan json-input!

Demo di sini: https://github.com/lovefamilychildrenhappiness/AngularCustomComponentValidation

Donato
sumber
0

Saya memulai Angular dan dalam kasus saya, masalahnya adalah saya tidak menyimpan file setelah menambahkan pernyataan 'impor'.

pengguna637563
sumber
0

Modul rute (tidak melihat ini sebagai jawaban)

Pertama periksa: jika Anda telah mendeklarasikan- dan mengekspor komponen di dalam modulnya, impor modul tempat Anda ingin menggunakannya dan beri nama komponen dengan benar di dalam HTML.

Jika tidak, Anda mungkin kehilangan modul di dalam modul perutean:
Ketika Anda memiliki modul perutean dengan rute yang merutekan ke komponen dari modul lain, penting bahwa Anda mengimpor modul itu dalam modul rute tersebut. Jika tidak, CLI Angular akan menampilkan kesalahan:component is not a known element .

Sebagai contoh

1) Memiliki struktur proyek berikut:

├───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) Di dalam todos-routing.module.tsAnda memiliki rute ke edit.todo.component.ts(tanpa mengimpor modulnya):

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

Rute hanya akan bekerja dengan baik! Namun ketika mengimpor sidebar.module.tsdalam edit-todo.module.tsAnda akan mendapatkan error: app-sidebar is not a known element.

Solusi: Karena Anda telah menambahkan rute ke edit-todo.component.tsdalam langkah 2, Anda harus menambahkannya edit-todo.module.tssebagai impor, setelah itu komponen bilah samping yang diimpor akan berfungsi!

Brampage
sumber
0

Saya menghadapi masalah yang sama. Dalam kasus saya, saya lupa mendeklarasikan komponen Induk di app.module.ts

Sebagai contoh jika Anda menggunakan <app-datapicker>pemilih dalam ToDayComponenttemplate, Anda harus mendeklarasikan keduanya ToDayComponentdan DatepickerComponentdi app.module.ts

Rajitha Kithuldeniya
sumber
0

Seharusnya Anda memiliki komponen:

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

Dan Anda mendapatkan kesalahan ini:

GALAT di src / app / app.component.ts: 6: 3 - error NG8001: 'pm-products' bukan elemen yang diketahui:

  1. Jika 'pm-products' adalah komponen Angular, maka verifikasi bahwa itu adalah bagian dari modul ini.

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

Pastikan Anda mengimpor komponen:

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 { }
cinta hidup
sumber
0

Pertanyaan ini mungkin tampak tua dan aneh, tetapi ketika saya mencoba memuat modul (lazy loading) dan mendapatkan kesalahan yang sama, saya menyadari bahwa saya kehilangan klausa ekspor untuk komponen yang dikirim sebagai bagian dari modul yang lebih besar.

Tautan Angular.io ini menjelaskan mengapa : Komponen / Layanan di dalam modul, tetap pribadi (atau dilindungi) secara default. Untuk mempublikasikannya, Anda harus mengekspornya.

Memperluas jawaban @Robin Djikof dengan contoh kode live-love @ , inilah yang secara teknis tidak ada dalam kasus saya (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 { }
SORE
sumber