Angular 4で@NgModule.entryComponentsを使用する方法
Angular 4: コンポーネントファクトリが見つからないエラー
Angular 4で、コンポーネントを動的にロードしようとすると、「Angular 4: no component factory found,did you add it to @NgModule.entryComponents ?」というエラーが発生することがあります。これは、コンポーネントファクトリが@NgModule.entryComponents
に登録されていないために発生します。
原因
このエラーが発生する理由は、コンポーネントファクトリが@NgModule.entryComponents
に登録されていないからです。@NgModule.entryComponents
は、動的にロードされるコンポーネントを登録するために使用されます。
解決策
このエラーを解決するには、以下の手順でコンポーネントファクトリを@NgModule.entryComponents
に登録する必要があります。
- コンポーネントファクトリファイルを作成します。
- コンポーネントファクトリファイルで、
@ComponentFactory
アノテーションを使用してコンポーネントファクトリを定義します。 @NgModule
アノテーションのentryComponents
プロパティに、作成したコンポーネントファクトリを追加します。
例
以下の例は、@NgModule.entryComponents
を使用してコンポーネントファクトリを登録する方法を示しています。
// コンポーネントファクトリファイル
import { Component, ComponentFactoryResolver } from '@angular/core';
@ComponentFactory({
selector: 'my-component',
templateUrl: './my-component.component.html'
})
export class MyComponent {
// ...
}
// AppModule
import { NgModule } from '@angular/core';
import { MyComponent } from './my-component.component';
@NgModule({
declarations: [
MyComponent
],
entryComponents: [
MyComponentFactory
]
})
export class AppModule {
// ...
}
この例では、MyComponent
というコンポーネントと、そのコンポーネントファクトリであるMyComponentFactory
を作成しています。MyComponentFactory
は@ComponentFactory
アノテーションを使用して定義されており、@NgModule.entryComponents
プロパティに追加されています。
補足
このエラーは、コンポーネントを動的にロードしようとすると発生します。コンポーネントを静的にロードする場合は、このエラーは発生しません。
また、このエラーは、コンポーネントファクトリが存在しない場合にも発生します。コンポーネントファクトリが存在するかどうかを確認するには、コンポーネントファイルを確認する必要があります。
<h1>My Component</h1>
<p>This is my component.</p>
// コンポーネントファイル
import { Component } from '@angular/core';
@Component({
selector: 'my-component',
templateUrl: './my-component.component.html'
})
export class MyComponent {
// ...
}
// コンポーネントファクトリファイル
import { Component, ComponentFactoryResolver } from '@angular/core';
@ComponentFactory({
selector: 'my-component',
templateUrl: './my-component.component.html'
})
export class MyComponentFactory {
constructor(private componentFactoryResolver: ComponentFactoryResolver) {
// ...
}
create(selector: string): ComponentRef<MyComponent> {
return this.componentFactoryResolver.resolveComponentFactory(MyComponent).create(selector);
}
}
// AppModule
import { NgModule } from '@angular/core';
import { MyComponent } from './my-component.component';
@NgModule({
declarations: [
MyComponent
],
entryComponents: [
MyComponentFactory
]
})
export class AppModule {
// ...
}
このサンプルコードを実行すると、MyComponent
が動的にロードされます。
Angular 4でコンポーネントファクトリを登録するその他の方法
@ViewChild
を使用すると、コンポーネントテンプレート内でコンポーネントファクトリを取得することができます。
<my-component #myComponent></my-component>
// コンポーネントファイル
import { Component, ViewChild } from '@angular/core';
import { MyComponentFactory } from './my-component.factory';
@Component({
selector: 'my-parent-component',
templateUrl: './my-parent-component.component.html'
})
export class MyParentComponent {
@ViewChild(MyComponentFactory) myComponentFactory: MyComponentFactory;
// ...
}
ComponentFactoryResolver
を使用すると、コード内でコンポーネントファクトリを取得することができます。
// コンポーネントファイル
import { Component, ComponentFactoryResolver } from '@angular/core';
import { MyComponentFactory } from './my-component.factory';
@Component({
selector: 'my-parent-component',
templateUrl: './my-parent-component.component.html'
})
export class MyParentComponent {
constructor(private componentFactoryResolver: ComponentFactoryResolver) {
// ...
}
createComponent() {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(MyComponent);
const componentRef = componentFactory.create('my-selector');
// ...
}
}
- コンポーネントテンプレート内でコンポーネントファクトリを取得する必要がある場合は、
@ViewChild
を使用する必要があります。 - コード内でコンポーネントファクトリを取得する必要がある場合は、
ComponentFactoryResolver
を使用する必要があります。
angular angular-webpack-starter