'องค์ประกอบ' เชิงมุม 2 ไม่ใช่องค์ประกอบที่รู้จัก


135

ฉันกำลังพยายามใช้ส่วนประกอบที่ฉันสร้างขึ้นภายใน AppModule ในโมดูลอื่น ๆ ฉันได้รับข้อผิดพลาดต่อไปนี้:

"Uncaught (ตามสัญญา): ข้อผิดพลาด: ข้อผิดพลาดในการแยกวิเคราะห์เทมเพลต:

"contact-box" ไม่ใช่องค์ประกอบที่รู้จัก:

  1. หาก 'contact-box' เป็นส่วนประกอบเชิงมุมให้ตรวจสอบว่าเป็นส่วนหนึ่งของโมดูลนี้
  2. หาก "contact-box" เป็นเว็บคอมโพเนนต์ให้เพิ่ม "CUSTOM_ELEMENTS_SCHEMA" ใน "@ NgModule.schemas" ของคอมโพเนนต์นี้เพื่อระงับข้อความนี้

โครงสร้างโครงการของฉันค่อนข้างง่าย: โครงสร้างโครงการโดยรวม

ฉันเก็บเพจของฉันไว้ในไดเร็กทอรีเพจโดยแต่ละเพจจะถูกเก็บไว้ในโมดูลที่แตกต่างกัน (เช่นโมดูลลูกค้า) และแต่ละโมดูลมีส่วนประกอบหลายอย่าง (เช่นส่วนประกอบรายการลูกค้าลูกค้าเพิ่มส่วนประกอบและอื่น ๆ ) ฉันต้องการใช้ ContactBoxComponent ของฉันภายในส่วนประกอบเหล่านั้น (ตัวอย่างเช่นในส่วนเพิ่มของลูกค้า)

อย่างที่คุณเห็นฉันสร้างส่วนประกอบกล่องผู้ติดต่อภายในไดเร็กทอรีวิดเจ็ตดังนั้นโดยพื้นฐานแล้วมันจะอยู่ภายใน AppModule ฉันเพิ่มการนำเข้า ContactBoxComponent ไปยัง app.module.ts และวางไว้ในรายการประกาศของ AppModule ไม่ได้ผลดังนั้นฉันจึงแก้ไขปัญหาของฉันและเพิ่ม ContactBoxComponent เพื่อส่งออกรายการด้วย ไม่ได้ช่วย ฉันยังลองใส่ ContactBoxComponent ใน customersAddComponent แล้วใส่อีกอันหนึ่ง (จากโมดูลอื่น) แต่ฉันได้รับข้อผิดพลาดว่ามีการประกาศหลายรายการ

ฉันขาดอะไรไป?


โครงสร้างโฟลเดอร์ของคุณไม่ใช่เรื่องง่าย มันสับสน ฉันขอแนะนำให้ทำตาม Angular Style Guide (ลิงก์ไม่ได้ระบุ b / c ที่พวกเขาเปลี่ยน) และใช้คำแนะนำโครงสร้างโฟลเดอร์จากนั้นตรวจสอบให้แน่ใจว่าคุณใช้โมดูลอย่างถูกต้อง นั่นคือความหมาย คุณไม่ได้ส่งออกหรือประกาศส่วนประกอบของคุณในโมดูลที่แอปนำเข้าในบางจุด
Joshua Michael Wagoner

ของฉันคำตอบที่เป็นประโยชน์สำหรับคำถามที่ถูกถาม ... 🙄
toastyghost

คำตอบ:


278

นี่คือ 5 ขั้นตอนที่ฉันทำเมื่อพบข้อผิดพลาดดังกล่าว

  • แน่ใจว่าชื่อถูกต้องหรือไม่? (ตรวจสอบตัวเลือกที่กำหนดไว้ในองค์ประกอบด้วย)
  • ประกาศส่วนประกอบในโมดูลหรือไม่
  • หากอยู่ในโมดูลอื่นให้ส่งออกส่วนประกอบ?
  • หากอยู่ในโมดูลอื่นให้นำเข้าโมดูลนั้นหรือไม่
  • รีสตาร์ท cli?

ฉันยังลองใส่ ContactBoxComponent ใน customersAddComponent แล้วใส่อีกอันหนึ่ง (จากโมดูลอื่น) แต่ฉันได้รับข้อผิดพลาดว่ามีการประกาศหลายรายการ

คุณไม่สามารถประกาศคอมโพเนนต์สองครั้ง คุณควรประกาศและส่งออกส่วนประกอบของคุณในโมดูลแยกใหม่ ถัดไปคุณควรนำเข้าโมดูลใหม่นี้ในทุกโมดูลที่คุณต้องการใช้ส่วนประกอบของคุณ

เป็นการยากที่จะบอกว่าคุณควรสร้างโมดูลใหม่เมื่อใดและเมื่อใดที่คุณไม่ควร ฉันมักจะสร้างโมดูลใหม่สำหรับทุกส่วนประกอบที่ฉันนำมาใช้ใหม่ เมื่อฉันมีส่วนประกอบบางอย่างที่ฉันใช้เกือบทุกที่ฉันใส่ไว้ในโมดูลเดียว เมื่อฉันมีส่วนประกอบที่ฉันไม่ได้ใช้ซ้ำฉันจะไม่สร้างโมดูลแยกต่างหากจนกว่าฉันจะต้องการมันที่อื่น

แม้ว่าการใส่ส่วนประกอบทั้งหมดของคุณไว้ในโมดูลเดียวอาจเป็นการดึงดูด แต่ก็ไม่ดีต่อประสิทธิภาพ ในขณะที่กำลังพัฒนาโมดูลจะต้องคอมไพล์ใหม่ทุกครั้งที่มีการเปลี่ยนแปลง ยิ่งโมดูลมีขนาดใหญ่ (ส่วนประกอบมากขึ้น) ก็จะยิ่งใช้เวลามากขึ้น การเปลี่ยนแปลงเล็กน้อยเป็นโมดูลใหญ่ต้องใช้เวลามากกว่าการเปลี่ยนแปลงเล็กน้อยในโมดูลขนาดเล็ก


6
ขั้นตอนของคุณไม่ได้ช่วยฉัน แต่อาจเป็นเพราะฉันยังใหม่กับ Angular 2 ดังนั้นฉันจะตอบพวกเขาและบางทีเราอาจจะหาวิธีแก้ปัญหาร่วมกัน ฉันแน่ใจว่าชื่อถูกต้องฉันประกาศคอมโพเนนต์ใน AppModule ฉันส่งออกส่วนประกอบใน AppModule และรีสตาร์ท cli ฉันลองนำเข้า AppModule ใน customersAddComponent ของฉันด้วย แต่มันส่งผลให้เกิดข้อผิดพลาด: ขนาดสแต็กการโทรสูงสุดเกิน (ฉันเดาว่าเราไม่ได้นำเข้า AppModule ใน Angular 2)
Aranha

7
คุณควรประกาศและส่งออกส่วนประกอบของคุณในโมดูลแยกส่วนไม่ใช่ใน AppModule ถัดไปคุณควรนำเข้าโมดูลใหม่นี้ในทุกโมดูลที่คุณต้องการเพื่อใช้ส่วนประกอบของคุณ
Robin Dijkhof

2
โอเคฉันเข้าใจแล้ว คำถามเดียวคือ: เมื่อฉันนำเข้าโมดูลที่สร้างขึ้นใหม่ (พูดว่า WidgetsModule) มันจะโหลดส่วนประกอบทั้งหมดที่ประกาศไว้ภายในใช่ไหม? นั่นเป็นค่าใช้จ่ายบางส่วน แต่บางทีฉันอาจเข้าใจผิดบางอย่าง แน่นอนฉันสามารถสร้าง ContactsBoxModule ได้ แต่นั่นเป็นสิ่งที่มากสำหรับส่วนประกอบเล็ก ๆ น้อย ๆ คำแนะนำใด ๆ ?
Aranha

5
ถูกต้องแล้ว. และยากที่จะบอกว่าคุณควรสร้างโมดูลใหม่เมื่อใดและเมื่อใดที่คุณไม่ควร ฉันมักจะสร้างโมดูลใหม่สำหรับทุกส่วนประกอบที่ฉันนำมาใช้ใหม่ เมื่อฉันมีส่วนประกอบบางอย่างที่ฉันใช้เกือบทุกที่ฉันใส่ไว้ในโมดูลเดียว เมื่อฉันมีส่วนประกอบที่ฉันไม่ได้ใช้ซ้ำฉันจะไม่สร้างโมดูลแยกต่างหากจนกว่าฉันจะต้องการมันที่อื่น
Robin Dijkhof

2
"ถ้าอยู่ในโมดูลอื่นให้ส่งออกส่วนประกอบหรือไม่" ทำงานให้ฉัน!
Steven

25

ฉันมีปัญหาที่คล้ายกัน ปรากฎว่าng generate component (ใช้ CLI เวอร์ชัน 7.1.4) เพิ่มการประกาศสำหรับคอมโพเนนต์ลูกลงใน AppModule แต่ไม่ใช่โมดูล TestBed ที่เลียนแบบ

"การทัวร์ของวีรบุรุษ" แอปตัวอย่างที่มีกับตัวเลือกHeroesComponent app-heroesแอปพลิเคดีวิ่งเมื่อเสิร์ฟ แต่ผลิตข้อผิดพลาดนี้:ng test 'app-heroes' is not a known elementการเพิ่มHeroesComponentด้วยตนเองในการประกาศในconfigureTestingModule(ในapp.component.spec.ts ) จะช่วยขจัดข้อผิดพลาดนี้

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

นี่เป็นปัญหาของฉัน - ลืมเพิ่มการนำเข้าในไฟล์ทดสอบ
Sellorio

17

ฉันมีปัญหาเดียวกันแน่นอน ก่อนที่จะลองใช้วิธีแก้ปัญหาบางอย่างที่โพสต์ไว้ที่นี่คุณอาจต้องการตรวจสอบว่าส่วนประกอบนั้นใช้งานไม่ได้จริงหรือไม่ สำหรับฉันข้อผิดพลาดปรากฏใน IDE (WebStorm) ของฉัน แต่ปรากฎว่ารหัสทำงานได้อย่างสมบูรณ์เมื่อฉันเรียกใช้ในเบราว์เซอร์

หลังจากที่ฉันปิดเทอร์มินัล (ซึ่งกำลังใช้งาน ng serve) และรีสตาร์ท IDE ของฉันข้อความก็หยุดแสดงขึ้น


ปัญหาเป็นปัญหาเฉพาะ ฉันมีปัญหาเดียวกันกับเว็บสตอร์ม Webstorm ไม่ได้รับแจ้งสำหรับการเปลี่ยนแปลงที่ทำด้วย angular-cli ดังนั้นคุณต้องรีสตาร์ท IDE เพื่อให้ 'เห็น' ส่วนประกอบใหม่ ๆ !
skiabox

2
ฉันมีปัญหาเดียวกันกับ VS Code แต่ใช้ Ionic 2 ในหน้ามันใช้งานได้ ในองค์ประกอบที่มีข้อผิดพลาดion- * ไม่ได้เป็นที่รู้จักกันในองค์ประกอบ ฉันได้ลองคำแนะนำของคุณเพื่อหยุดการให้บริการไอออนิกและรีสตาร์ท IDE แต่ไม่มีอะไรได้ผล คุณรู้วิธีแก้ปัญหาอื่นหรือไม่? อย่างไรก็ตาม - รหัสใช้งานได้อยู่แล้ว
Sebastian Ortmann

มีปัญหาเดียวกันกับ VSCode หลังจากรีสตาร์ทตัวแก้ไขข้อความก็หายไป
quicklikerabbit

3

ฉันมีปัญหาความกว้างเดียวกัน php storm เวอร์ชัน 2017.3 สิ่งนี้แก้ไขให้ฉัน: ฟอรัมการสนับสนุน intellij

มันเป็นข้อผิดพลาดของบริการภาษา @ รูปสามเหลี่ยม: https://www.npmjs.com/package/@angular/language-service


นอกจากนี้ยังได้รับการแก้ไขสำหรับ webstorm 2018.3
Mohamed Mahmoud

1

ในกรณีของฉัน app ของฉันมีหลายชั้นของโมดูลเพื่อโมดูลผมพยายามที่จะนำเข้าจะต้องมีการเพิ่มเข้าไปในปกครองโมดูลที่ใช้จริงมันแทนpages.module.tsapp.module.ts


0

ฉันพบปัญหาเดียวกันและมันเกิดขึ้นเนื่องจากโมดูลคุณลักษณะที่แตกต่างกันรวมส่วนประกอบนี้โดยไม่ได้ตั้งใจ เมื่อนำออกจากคุณสมบัติอื่นก็ใช้งานได้!


0

ปัญหาในกรณีของฉันคือไม่มีการประกาศส่วนประกอบในโมดูล แต่หลังจากเพิ่มการประกาศแล้วข้อผิดพลาดก็ยังคงอยู่ ฉันได้หยุดเซิร์ฟเวอร์และสร้างโครงการทั้งหมดใน VS Code เพื่อให้ข้อผิดพลาดหายไป


0

กรอบงานที่ซับซ้อนนี้ทำให้ฉันรู้สึกแย่ เนื่องจากคุณได้กำหนดองค์ประกอบที่กำหนดเองในเทมเพลตของส่วนประกอบอื่นของโมดูล SAME คุณจึงไม่จำเป็นต้องใช้การส่งออกในโมดูล (เช่น app.module.ts) คุณเพียงแค่ระบุการประกาศในคำสั่ง @NgModule ของโมดูลดังกล่าว:

// app.module.ts

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

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

คุณไม่จำเป็นต้องนำเข้าJsonInputComponent(ในตัวอย่างนี้) ลงในAppComponent(ในตัวอย่างนี้) เพื่อใช้JsonInputComponentส่วนประกอบที่กำหนดเองในAppComponentเทมเพลต คุณเพียงแค่ต้องนำหน้าส่วนประกอบที่กำหนดเองด้วยชื่อโมดูลที่มีการกำหนดส่วนประกอบทั้งสอง (เช่นแอป):

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

สังเกตว่า app-json-input ไม่ใช่ json-input!

สาธิตที่นี่: https://github.com/lovefamilychildrenhappiness/AngularCustomComponentValidation


0

ฉันกำลังเริ่ม Angular และในกรณีของฉันปัญหาคือฉันไม่ได้บันทึกไฟล์หลังจากเพิ่มคำสั่ง 'นำเข้า'


0

โมดูลเส้นทาง (ไม่เห็นว่านี่เป็นคำตอบ)

ตรวจสอบขั้นแรก: หากคุณได้ประกาศและส่งออกส่วนประกอบภายในโมดูลให้นำเข้าโมดูลที่คุณต้องการใช้และตั้งชื่อส่วนประกอบให้ถูกต้องภายใน HTML

มิฉะนั้นคุณอาจพลาดโมดูลภายในโมดูลเส้นทางของคุณ:
เมื่อคุณมีโมดูลการกำหนดเส้นทางที่มีเส้นทางที่กำหนดเส้นทางไปยังส่วนประกอบจากโมดูลอื่นสิ่งสำคัญคือคุณต้องนำเข้าโมดูลนั้นภายในโมดูลเส้นทางนั้น มิฉะนั้น Angular CLI จะแสดงข้อผิดพลาด:component is not a known elementเชิงมุมจะแสดงข้อผิดพลาด:

ตัวอย่างเช่น

1) มีโครงสร้างโครงการดังนี้

├───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) ภายในtodos-routing.module.tsคุณมีเส้นทางไปยังedit.todo.component.ts(โดยไม่ต้องนำเข้าโมดูล):

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

เส้นทางจะใช้ได้ดี! อย่างไรก็ตามเมื่อนำเข้าsidebar.module.tsภายในedit-todo.module.tsคุณจะได้รับข้อผิดพลาด:app-sidebar is not a known elementคุณจะได้รับข้อผิดพลาด:

แก้ไข:เนื่องจากคุณได้เพิ่มเส้นทางedit-todo.component.tsในขั้นตอนที่ 2 แล้วคุณจะต้องเพิ่มedit-todo.module.tsเป็นการนำเข้าหลังจากนั้นส่วนประกอบของแถบด้านข้างที่นำเข้าจึงจะทำงานได้!


0

ฉันประสบปัญหาเดียวกัน ในกรณีของฉันฉันลืมที่จะประกาศองค์ประกอบหลักใน app.module.ts

ตัวอย่างเช่นหากคุณใช้<app-datapicker>ตัวเลือกในToDayComponentเทมเพลตคุณควรประกาศทั้งสองToDayComponentและDatepickerComponentในapp.module.ts


0

สมมติว่าคุณมีส่วนประกอบ:

ผลิตภัณฑ์ list.component.ts:

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

และคุณได้รับข้อผิดพลาดนี้:

ข้อผิดพลาดใน src / app / app.component.ts: 6: 3 - ข้อผิดพลาด NG8001: 'pm-products' ไม่ใช่องค์ประกอบที่รู้จัก:

  1. หาก 'pm-products' เป็นส่วนประกอบเชิงมุมให้ตรวจสอบว่าเป็นส่วนหนึ่งของโมดูลนี้

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

ตรวจสอบให้แน่ใจว่าคุณนำเข้าส่วนประกอบ:

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

คำถามนี้อาจดูเก่าและแปลก แต่เมื่อฉันพยายามโหลดโมดูล (ขี้เกียจโหลด) และได้รับข้อผิดพลาดเดียวกันฉันรู้ว่าฉันไม่มีส่วนส่งออกสำหรับส่วนประกอบที่จัดส่งเป็นส่วนหนึ่งของโมดูลขนาดใหญ่

ลิงก์ Angular.ioนี้อธิบายถึงสาเหตุ : Components / บริการภายในโมดูลยังคงส่วนตัว (หรือป้องกัน) โดยค่าเริ่มต้น คุณต้องส่งออกเพื่อให้เป็นสาธารณะ

การขยายคำตอบของ @Robin Djikofด้วยตัวอย่างโค้ด @ live-loveนี่คือสิ่งที่ขาดหายไปในทางเทคนิคในกรณีของฉัน (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 { }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.