Angular 4에서 발생하는 "No component factory found, did you add it to @NgModule.entryComponents?" 오류 해결 방법
Angular 4에서 "No component factory found, did you add it to @NgModule.entryComponents?" 오류는 일반적으로 컴포넌트를 동적으로 로드하려고 할 때 발생하며 다음과 같은 두 가지 경우에 발생합니다.
- 컴포넌트가 라우팅 모듈에 속하지 않을 때
컴포넌트를 라우팅 모듈에 속하지 않으면 컴포넌트 팩토리를 찾을 수 없어 오류가 발생합니다. 라우팅 모듈은 컴포넌트 팩토리를 저장하고 컴포넌트를 동적으로 로드하는 데 필요한 정보를 제공합니다.
- 컴포넌트가 모듈의
entryComponents
에 추가되지 않은 경우
컴포넌트를 동적으로 로드하려면 컴포넌트를 모듈의 entryComponents
배열에 추가해야 합니다. entryComponents
는 동적으로 로드될 수 있는 컴포넌트 목록을 지정하는 속성입니다.
오류 해결 방법
오류를 해결하려면 다음 두 가지 방법 중 하나를 사용할 수 있습니다.
- 컴포넌트를 라우팅 모듈에 추가
컴포넌트를 라우팅 모듈에 추가하면 컴포넌트 팩토리를 자동으로 찾을 수 있습니다. 라우팅 모듈에 컴포넌트를 추가하려면 다음 단계를 수행하십시오.
- 컴포넌트를 라우팅 모듈의
declarations
배열에 추가합니다. - 컴포넌트를 위한 라우팅 경로를 설정합니다.
컴포넌트를 모듈의 entryComponents
배열에 추가하면 컴포넌트를 동적으로 로드할 수 있습니다. 컴포넌트를 entryComponents
에 추가하려면 다음 단계를 수행하십시오.
- 컴포넌트를 모듈의
imports
배열에 추가합니다.
다음은 두 가지 방법의 예시입니다.
// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { MyComponent } from './my-component/my-component.component';
const routes: Routes = [
{ path: '', component: AppComponent },
{ path: 'my-component', component: MyComponent }
];
@NgModule({
imports: [
RouterModule.forRoot(routes)
],
exports: [
RouterModule
],
declarations: [
AppComponent
],
bootstrap: [
AppComponent
]
})
export class AppModule { }
// my-component.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
})
export class MyComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { MyComponent } from './my-component/my-component.component';
@NgModule({
imports: [
BrowserModule
],
declarations: [
AppComponent,
MyComponent
],
bootstrap: [
AppComponent
],
entryComponents: [
MyComponent
]
})
export class AppModule { }
// my-component.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
})
export class MyComponent implements OnInit {
constructor() { }
예제 코드
app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { MyComponent } from './my-component/my-component.component';
const routes: Routes = [
{ path: '', component: AppComponent },
{ path: 'my-component', component: MyComponent }
];
@NgModule({
imports: [
RouterModule.forRoot(routes)
],
exports: [
RouterModule
],
declarations: [
AppComponent,
MyComponent
],
bootstrap: [
AppComponent
]
})
export class AppModule { }
my-component.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
})
export class MyComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { MyComponent } from './my-component/my-component.component';
@NgModule({
imports: [
BrowserModule
],
declarations: [
AppComponent,
MyComponent
],
bootstrap: [
AppComponent
],
entryComponents: [
MyComponent
]
})
export class AppModule { }
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
})
export class MyComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
Angular 4에서 "No component factory found, did you add it to @NgModule.entryComponents?" 오류를 해결하는 대체 방법
@ViewChild를 사용하여 컴포넌트를 동적으로 로드
@ViewChild
데코레이터를 사용하여 컴포넌트 템플릿에서 컴포넌트를 동적으로 로드할 수 있습니다. @ViewChild
를 사용하려면 다음 단계를 수행하십시오.
- 컴포넌트 템플릿에 컴포넌트를 삽입할 위치를 지정합니다.
@ViewChild
데코레이터를 사용하여 컴포넌트 클래스를 참조합니다.- 컴포넌트 인스턴스를 가져오기 위해
ngAfterViewInit
라이프 사이클 훅을 사용합니다.
app.component.html
<div #container></div>
import { Component, AfterViewInit, ViewChild } from '@angular/core';
import { MyComponent } from './my-component/my-component.component';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
@ViewChild('container') container: any;
constructor() { }
ngAfterViewInit() {
const componentFactory = this.container.componentFactoryResolver.resolveComponentFactory(MyComponent);
const componentRef = this.container.createComponent(componentFactory);
}
}
ComponentFactoryResolver를 사용하여 컴포넌트를 동적으로 로드
ComponentFactoryResolver
클래스를 사용하여 컴포넌트 팩토리를 직접 생성하고 컴포넌트를 동적으로 로드할 수 있습니다. ComponentFactoryResolver
를 사용하려면 다음 단계를 수행하십시오.
ComponentFactoryResolver
를 주입합니다.- 컴포넌트 팩토리를 사용하여 컴포넌트 인스턴스를 생성합니다.
import { Component, AfterViewInit, Injector, ViewChild } from '@angular/core';
import { MyComponent } from './my-component/my-component.component';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
constructor(private injector: Injector) { }
ngAfterViewInit() {
const componentFactoryResolver = this.injector.get(ComponentFactoryResolver);
const componentFactory = componentFactoryResolver.resolveComponentFactory(MyComponent);
const componentRef = componentFactory.create(this.injector);
}
}
ng-template을 사용하여 컴포넌트를 동적으로 로드
ng-template
을 사용하여 컴포넌트 템플릿에 템플릿을 동적으로 삽입할 수 있습니다. ng-template
을 사용하려면 다음 단계를 수행하십시오.
ng-template
태그를 사용하여 템플릿을 정의합니다.*ngIf
지시문을 사용하여 템플릿을 표시하거나 숨깁니다.
<div *ngIf="showMyComponent">
<my-component></my-component>
</div>
<ng-template #myTemplate>
<my-component></my-component>
</ng-template>
angular angular-webpack-starter