팁: 이 가이드 문서는 핵심 가이드 이후 내용을 다룹니다. 아직 Angular에 익숙하지 않다면 해당 문서를 먼저 읽어보세요.
컴포넌트는 템플릿에 사용하는 방식 외에 동적으로 렌더링 할 수도 있습니다.
템플릿에서 NgComponentOutlet
를 사용하거나 TypeScript 코드에서 ViewContainerRef
를 사용하면 됩니다.
NgComponentOutlet
사용하기
NgComponentOutlet
는 템플릿에서 컴포넌트를 동적으로 렌더링하는 구조 디렉티브입니다.
@Component({ ... })export class AdminBio { /* ... */ }@Component({ ... })export class StandardBio { /* ... */ }@Component({ ..., template: ` <p>Profile for {{user.name}}</p> <ng-container *ngComponentOutlet="getBioComponent()" /> `})export class CustomDialog { user = input.required<User>(); getBioComponent() { return this.user().isAdmin ? AdminBio : StandardBio; }}
이 디렉티브에 대해 자세하게 알아보려면 NgComponentOutlet API 문서를 참고하세요.
ViewContainerRef
사용하기
뷰 컨테이너 는 컴포넌트 트리에서 내용물을 담는 노드를 의미합니다.
그리고 컴포넌트나 디렉티브는 ViewContainerRef
를 의존성 객체로 주입받아서 DOM에 존재하는 뷰 컨테이너를 참조할 수 있습니다.
ViewContainerRef
객체의 createComponent
메서드를 사용하면 컴포넌트를 동적으로 생성하고 렌더링 할 수 있습니다.
ViewContainerRef
를 사용해서 컴포넌트를 생성하면 Angular는 ViewContainerRef
로 참조한 컴포넌트나 디렉티브 바로 옆에 DOM을 추가합니다.
@Component({ selector: 'leaf-content', template: ` This is the leaf content `,})export class LeafContent {}@Component({ selector: 'outer-container', template: ` <p>This is the start of the outer container</p> <inner-item /> <p>This is the end of the outer container</p> `,})export class OuterContainer {}@Component({ selector: 'inner-item', template: ` <button (click)="loadContent()">Load content</button> `,})export class InnerItem { private viewContainer = inject(ViewContainerRef); loadContent() { this.viewContainer.createComponent(LeafContent); }}
위 예제코드에서 사용자가 "Load content" 버튼을 클릭하면 아래 DOM 구조가 화면에 렌더링 됩니다.
<outer-container> <p>This is the start of the outer container</p> <inner-item> <button>Load content</button> </inner-item> <leaf-content>This is the leaf content</leaf-content> <p>This is the end of the outer container</p></outer-container>
컴포넌트 지연 로딩
NgComponentOutlet
이나 ViewContainerRef
를 사용해서 컴포넌트를 렌더링하면 표준 JavaScript 동적 로딩에 따라 지연로딩됩니다.
@Component({ ..., template: ` <section> <h2>Basic settings</h2> <basic-settings /> </section> <section> <h2>Advanced settings</h2> <button (click)="loadAdvanced()" *ngIf="!advancedSettings"> Load advanced settings </button> <ng-container *ngComponentOutlet="advancedSettings" /> </section> `})export class AdminSettings { advancedSettings: {new(): AdvancedSettings} | undefined; async loadAdvanced() { const { AdvancedSettings } = await import('path/to/advanced_settings.js'); this.advancedSettings = AdvancedSettings; }}
이렇게 구현하면 사용자가 버튼을 클릭했을 때 AdvancedSettings
컴포넌트가 동적으로 로딩되어 화면에 렌더링됩니다.