FE/Angular

[Angular] ngComponentOutlet과 ngSwitchCase로 동적 컴포넌트 표시

monkeykim 2024. 11. 7. 00:59

웹 애플리케이션을 개발하다 보면, 사용자의 선택에 따라 다른 컴포넌트를 보여줘야 하는 상황이 있습니다. 예를 들어, 사용자가 선택한 메뉴에 따라 페이지 내용이 바뀌거나, 특정 조건에 따라 다른 컴포넌트를 로딩하는 것이 필요할 때가 많습니다. Angular에서는 ngComponentOutlet과 ngSwitchCase를 사용하여 이러한 기능을 쉽게 구현할 수 있습니다.


ngComponentOutlet과 ngSwitchCase란?

  • ngComponentOutlet: 컴포넌트 클래스를 직접 참조하여 동적 컴포넌트를 로드할 수 있게 하는 Angular 디렉티브입니다. 이 디렉티브를 사용하면, 코드에서 컴포넌트를 선택하고 해당 위치에 동적으로 삽입할 수 있습니다.
  • ngSwitchCase: 여러 옵션 중에서 조건에 맞는 콘텐츠를 표시하는 조건부 렌더링 디렉티브입니다. *ngSwitch와 함께 사용하여 다양한 케이스를 구분해 콘텐츠를 렌더링할 수 있습니다.

동적 컴포넌트와 조건별 콘텐츠 표시하기

1. 프로젝트 설정

이 예제에서는 세 가지 컴포넌트(HomeComponent, AboutComponent, ContactComponent)를 생성하고, 선택한 옵션에 따라 해당 컴포넌트를 표시하는 방식을 보여드리겠습니다.

2. 컴포넌트 생성

먼저, Angular CLI를 사용해 컴포넌트를 생성합니다.

ng generate component Home
ng generate component About
ng generate component Contact

각 컴포넌트의 HTML 파일에 간단한 메시지를 추가합니다.

 

  • home.component.html
    <p>Welcome to the Home Page!</p>
  • about.component.html
     
    <p>About Us: Learn more about our mission.</p>
  • contact.component.html
     
    <p>Contact Us: Reach out for more information.</p>

3. AppComponent에서 ngComponentOutlet을 사용해 동적 컴포넌트 표시

이제 AppComponent에서 동적으로 컴포넌트를 표시해 보겠습니다.

app.component.ts

import { Component } from '@angular/core';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
import { ContactComponent } from './contact/contact.component';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
})
export class AppComponent {
  // 현재 선택된 컴포넌트를 저장하는 변수
  selectedComponent: any = HomeComponent;

  // 컴포넌트를 변경하는 메서드
  loadComponent(componentName: string) {
    switch (componentName) {
      case 'home':
        this.selectedComponent = HomeComponent;
        break;
      case 'about':
        this.selectedComponent = AboutComponent;
        break;
      case 'contact':
        this.selectedComponent = ContactComponent;
        break;
      default:
        this.selectedComponent = HomeComponent;
        break;
    }
  }
}

 

app.component.html

<!-- 버튼을 눌러 컴포넌트 변경 -->
<button (click)="loadComponent('home')">Home</button>
<button (click)="loadComponent('about')">About</button>
<button (click)="loadComponent('contact')">Contact</button>

<!-- ngComponentOutlet을 사용하여 동적으로 선택한 컴포넌트 표시 -->
<ng-container *ngComponentOutlet="selectedComponent"></ng-container>

이제 버튼을 클릭할 때마다 loadComponent 메서드가 호출되어 selectedComponent가 변경됩니다. 이 값이 바뀌면 *ngComponentOutlet이 해당 컴포넌트를 로드하여 표시합니다.

4. ngSwitchCase를 사용해 조건별 콘텐츠 표시하기

이번에는 ngSwitch와 ngSwitchCase를 사용해 조건에 따라 다른 콘텐츠를 보여주는 방법을 살펴보겠습니다. 이 방법은 하나의 영역에서 여러 콘텐츠를 조건에 따라 표시해야 할 때 유용합니다.

app.component.html

<!-- 선택된 페이지를 보여주기 위한 select box -->
<select [(ngModel)]="selectedPage">
  <option value="home">Home</option>
  <option value="about">About</option>
  <option value="contact">Contact</option>
</select>

<!-- ngSwitch와 ngSwitchCase를 사용해 조건에 맞는 콘텐츠 표시 -->
<div [ngSwitch]="selectedPage">
  <div *ngSwitchCase="'home'">
    <app-home></app-home>
  </div>
  <div *ngSwitchCase="'about'">
    <app-about></app-about>
  </div>
  <div *ngSwitchCase="'contact'">
    <app-contact></app-contact>
  </div>
  <div *ngSwitchDefault>
    <p>Select a page to display its content.</p>
  </div>
</div>

5. selectedPage 변수 설정

selectedPage 변수는 select 박스의 선택에 따라 값을 변경하도록 설정해야 합니다.

app.component.ts

export class AppComponent {
  selectedPage: string = 'home';
}

ngComponentOutlet과 ngSwitchCase의 장단점

ngComponentOutlet

장점

  1. 유연한 컴포넌트 로딩: 컴포넌트를 직접 참조하여 로드할 수 있어 다양한 컴포넌트를 쉽게 동적으로 불러올 수 있습니다.
  2. 코드 분리: 컴포넌트마다 별도의 클래스를 참조하여 필요한 경우만 로딩하기 때문에, 코드가 더 깔끔하게 관리됩니다.

단점

  1. 입력 및 출력 처리의 어려움: 동적으로 로드된 컴포넌트에 @Input이나 @Output을 직접 바인딩하기 어렵습니다. 이를 해결하려면 Angular의 ComponentFactoryResolver와 같은 더 복잡한 방식이 필요합니다.
  2. 간단한 조건에는 불필요하게 복잡: 단순히 텍스트나 간단한 콘텐츠를 조건에 따라 표시하는 데에는 다소 복잡하게 느껴질 수 있습니다.

ngSwitchCase

장점

  1. 간단하고 읽기 쉬운 구조: 여러 조건에 따라 콘텐츠를 변경할 때 ngSwitch와 ngSwitchCase를 사용하면 코드가 단순하고 가독성이 좋습니다.
  2. 조건별로 다양한 콘텐츠 표시 가능: 텍스트, HTML 구조, 컴포넌트 등 다양한 콘텐츠를 조건에 따라 쉽게 표시할 수 있습니다.

단점

  1. 유지보수 어려움: 컴포넌트가 많아지면 ngSwitchCase 블록이 길어질 수 있어, 코드가 복잡해질 수 있습니다.
  2. 재사용성 제한: 컴포넌트 참조가 아닌 정적인 HTML 구조에 적합해, 많은 컴포넌트를 동적으로 불러오는 상황에는 적합하지 않습니다.

결론

  • 여러 컴포넌트를 동적으로 로딩해야 하는 경우: ngComponentOutlet이 더 적합합니다. 다양한 컴포넌트를 유연하게 불러올 수 있고, 조건에 따라 컴포넌트를 교체할 수 있습니다.
  • 단순한 조건부 콘텐츠 표시가 필요한 경우: ngSwitchCase가 더 간편하고 가독성이 좋습니다. 텍스트, 간단한 구조 또는 몇 개의 컴포넌트를 조건에 따라 선택하는 경우라면 ngSwitchCase를 사용하는 것이 효율적입니다.