Angular 2「コンポーネント」は既知の要素ではありません


134

AppModule内で作成したコンポーネントを他のモジュールで使用しようとしています。ただし、次のエラーが発生します。

「キャッチされていません(約束されています):エラー:テンプレート解析エラー:

'contacts-box'は既知の要素ではありません:

  1. 「contacts-box」がAngularコンポーネントである場合、それがこのモジュールの一部であることを確認してください。
  2. 「contacts-box」がWebコンポーネントの場合は、このコンポーネントの「@ NgModule.schemas」に「CUSTOM_ELEMENTS_SCHEMA」を追加して、このメッセージを抑制します。

私のプロジェクト構造は非常に単純です: プロジェクト全体の構造

ページをページディレクトリに保存します。各ページは異なるモジュール(customers-moduleなど)に保持され、各モジュールには複数のコンポーネント(customers-list-component、customers-add-componentなど)があります。これらのコンポーネント内で(つまり、customers-add-component内などで)ContactBoxComponentを使用したいと思います。

ご覧のとおり、widgetsディレクトリ内に連絡先ボックスコンポーネントを作成したので、基本的にはAppModule内にあります。ContactBoxComponentインポートをapp.module.tsに追加し、AppModuleの宣言リストに追加しました。それは機能しなかったので、問題をグーグルで調べて、ContactBoxComponentをエクスポートリストにも追加しました。助けにはならなかった。また、ContactBoxComponentをCustomersAddComponentに配置し、次に別のモジュール(異なるモジュールから)に配置しようとしましたが、複数の宣言があるというエラーが発生しました。

何が欠けていますか?


フォルダ構造は単純ではありません。ややこしい。私はAngular Style Guide(リンクは提供されていません)に従い、フォルダ構造の提案を使用して、モジュールが正しく使用されていることを確認することをお勧めします。これが意味することです。ある時点で、アプリが取り込んだモジュールでコンポーネントをエクスポートまたは宣言していない。
ジョシュアマイケルワゴナー

回答:


277

このようなエラーが発生したときに実行する5つの手順は次のとおりです。

  • 名前は正しいですか?(コンポーネントで定義されているセレクターも確認してください)
  • モジュールでコンポーネントを宣言しますか?
  • 別のモジュールにある場合、コンポーネントをエクスポートしますか?
  • 別のモジュールにある場合は、そのモジュールをインポートしますか?
  • CLIを再起動しますか?

また、ContactBoxComponentをCustomersAddComponentに配置し、次に別のモジュール(異なるモジュールから)に配置しようとしましたが、複数の宣言があるというエラーが発生しました。

コンポーネントを2回宣言することはできません。コンポーネントを宣言し、新しい別のモジュールでエクスポートする必要があります。次に、コンポーネントを使用するすべてのモジュールにこの新しいモジュールをインポートする必要があります。

新しいモジュールを作成する必要がある場合と作成しない場合を区別することは困難です。私は通常、再利用するコンポーネントごとに新しいモジュールを作成します。ほぼすべての場所で使用するコンポーネントがある場合、それらを単一のモジュールに配置します。再利用しないコンポーネントがある場合、別の場所で必要になるまで別のモジュールを作成しません。

すべてのコンポーネントを1つのモジュールに配置するのは魅力的ですが、これはパフォーマンスに悪影響を及ぼします。開発中、モジュールは変更が行われるたびに再コンパイルする必要があります。モジュールが大きいほど(コンポーネントが多いほど)、時間がかかります。大きなモジュールに小さな変更を加えると、小さなモジュールに小さな変更を加えるよりも時間がかかります。


6
あなたのステップは私を助けませんでしたが、おそらく私がAngular 2にかなり慣れていないためかもしれません。名前が正しいことは確かです。AppModuleでコンポーネントを宣言し、AppModuleでコンポーネントをエクスポートして、CLIを再起動しました。CustomersAddComponentにAppModuleをインポートしようとしましたが、エラーが発生しました:最大コールスタックサイズを超えました(Angular 2にAppModuleをインポートしないと思います)。
Aranha 2017年

7
コンポーネントは、AppModuleではなく別のモジュールで宣言してエクスポートする必要があります。次に、コンポーネントを使用するために、この新しいモジュールをすべてのモジュールにインポートする必要があります。
Robin Dijkhof 2017年

2
さて、私は今それを手に入れました。唯一の問題は、新しく作成されたモジュール(たとえば、WidgetsModule)をインポートすると、内部で宣言されているコンポーネントがすべてロードされるということです。それは多少のオーバーヘッドですが、多分私は何かを誤解しています。もちろん、ContactsBoxModuleを作成することもできますが、これは1つの小さなコンポーネントの場合と同じです。ヒントはありますか?
アラハ2017年

5
そうです。また、いつ新しいモジュールを作成する必要があるのか​​、いつ作成しないのかを判断するのは困難です。私は通常、再利用するコンポーネントごとに新しいモジュールを作成します。ほぼすべての場所で使用するコンポーネントがある場合、それらを単一のモジュールに配置します。再利用しないコンポーネントがある場合、別の場所で必要になるまで別のモジュールを作成しません。
Robin Dijkhof 2017年

2
「別のモジュールにある場合、コンポーネントをエクスポートしますか?」私のために働いた!
Steven

25

同様の問題がありました。ng generate component(CLIバージョン7.1.4を使用して)子コンポーネントの宣言をAppModuleに追加しますが、それをエミュレートするTestBedモジュールには追加しないことがわかりました。

「Tour of Heroes」サンプルアプリにはHeroesComponentwithセレクターが含まれていapp-heroesます。アプリは配信時に問題なく動作ng testしましたが、次のエラーメッセージが表示されました:'app-heroes' is not a known element。(の)のHeroesComponent宣言に手動で追加すると、このエラーが解消されます。configureTestingModuleapp.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 再起動すると、メッセージが表示されなくなりました。


問題はIDE固有です。ウェブストームでも同じ問題があります。angular-cliで行われた変更についてはWebstormに通知されないため、新しいコンポーネントを「表示」するには、IDEを再起動する必要があります。
skiabox 2018年

2
私はVSコードで同じ問題を抱えていますが、Ionic 2で問題があります。ページで機能します。コンポーネントにエラーion- *が既知の要素ではないというエラーがあります。イオンサービスを停止してIDEを再起動するよう提案しましたが、何も機能しません。これに対する別の解決策を知っていますか?ちなみに-コードはとにかく動作します。
Sebastian Ortmann、2018年

VSCodeでも同じ問題がありました。エディターを再起動した後、メッセージは消えました。
quicklikerabbit

3

私は同じ問題の幅のphpストームバージョン2017.3を持っています。これは私のためにそれを修正します: intellijサポートフォーラム

エラー幅@angular言語サービス:https ://www.npmjs.com/package/@angular/language-service


これにより、ウェブストーム2018.3の問題も修正されました
Mohamed Mahmoud

1

私の場合、アプリには複数のモジュールレイヤーがあったため、インポートしようとしたモジュールはpages.module.ts、ではなく、実際に使用するモジュールの親に追加する必要がありましたapp.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
  ],
  ...

テンプレートでカスタムコンポーネントを使用するためJsonInputComponentAppComponent(この例では)を(この例では)にインポートする必要はありません。両方のコンポーネントが定義されているモジュール名(例:app)をカスタムコンポーネントの前に付けるだけです。JsonInputComponentAppComponent

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

json-inputではなくapp-json-inputに注意してください!

ここのデモ:https : //github.com/lovefamilychildrenhappiness/AngularCustomComponentValidation


0

私はAngularを始めていますが、私の場合、問題は 'import'ステートメントを追加した後にファイルを保存しなかったことです。


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>セレクタを使用している場合の例として、app.module.tsToDayComponent両方ToDayComponentで宣言する必要DatepickerComponentがあります


0

おそらくあなたはコンポーネントを持っています:

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

そして、あなたはこのエラーを受け取ります:

src / app / app.component.ts:6:3のエラー-エラーNG8001: 'pm-products'は既知の要素ではありません:

  1. 「pm-products」がAngularコンポーネントの場合は、それがこのモジュールの一部であることを確認してください。

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

この質問は古くて奇妙に思えるかもしれませんが、モジュールをロードしようとすると(レイジーロード)、同じエラーが発生し、大きなモジュールの一部として出荷されたコンポーネントのexports句がないことに気付きました

このAngular.ioリンクは、理由を説明します。モジュール内のコンポーネント/サービスは、デフォルトでプライベート(または保護)のままです。それらを公開するには、それらをエクスポートする必要があります。

@ live-loveコードサンプル@Robin Djikofの答えを拡張すると、これは私の場合技術的に欠けていたものです(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.