본문 바로가기

개발 공부/Angular

@ContentChild와 @ContentChildren 활용

Angular @ContentChild와 @ContentChildren 활용

@ViewChild@ViewChildren은 같은 컴포넌트 내에서 뷰 요소를 참조하는데 사용됩니다.

반면, @ContentChild@ContentChildren은 부모 컴포넌트가 ng-content를 통해 전달받은 자식 컴포넌트나 요소를 참조할 때 사용됩니다.

 

@ContentChild의 개념 및 활용

@ContentChild 개요

@ContentChildng-content를 통해 삽입된 단일 자식 요소를 참조하는 데 사용됩니다.

2.2 예제: 부모 컴포넌트가 자식의 메서드 호출하기

// child.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-child',
  template: `<p>자식 컴포넌트</p>`
})
export class ChildComponent {
  showMessage() {
    return '자식 컴포넌트의 메시지';
  }
}
// parent.component.ts
import { Component, ContentChild, AfterContentInit } from '@angular/core';
import { ChildComponent } from './child.component';

@Component({
  selector: 'app-parent',
  template: `
    <ng-content></ng-content>
    <button (click)="showChildMessage()">자식 메시지 출력</button>
  `
})
export class ParentComponent implements AfterContentInit {
  @ContentChild(ChildComponent) child!: ChildComponent;

  ngAfterContentInit() {
    console.log('자식 컴포넌트 접근 가능:', this.child.showMessage());
  }

  showChildMessage() {
    alert(this.child.showMessage());
  }
}
<!-- app.component.html -->
<app-parent>
  <app-child></app-child>
</app-parent>
  • @ContentChild(ChildComponent)를 사용해 부모 컴포넌트가 자식의 인스턴스를 참조합니다.
  • ngAfterContentInit()에서 showMessage()를 호출하여 자식 컴포넌트의 데이터를 활용합니다.
  • 버튼 클릭 시 showChildMessage()가 호출되어 자식의 메시지가 표시됩니다.
 

@ContentChildren의 개념 및 활용

@ContentChildren 개요

@ContentChildren은 여러 개의 자식 컴포넌트를 QueryList 형태로 참조할 때 사용됩니다.

부모가 여러 개의 자식 컴포넌트를 관리하기

// item.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-item',
  template: `<p>아이템 컴포넌트</p>`
})
export class ItemComponent {
  getItemName() {
    return '아이템 데이터';
  }
}
// parent.component.ts
import { Component, ContentChildren, QueryList, AfterContentInit } from '@angular/core';
import { ItemComponent } from './item.component';

@Component({
  selector: 'app-parent',
  template: `
    <ng-content></ng-content>
    <button (click)="logItemData()">아이템 데이터 출력</button>
  `
})
export class ParentComponent implements AfterContentInit {
  @ContentChildren(ItemComponent) items!: QueryList<ItemComponent>;

  ngAfterContentInit() {
    this.items.forEach((item, index) => {
      console.log(`아이템 ${index + 1}:`, item.getItemName());
    });
  }

  logItemData() {
    this.items.forEach((item, index) => {
      console.log(`아이템 ${index + 1}:`, item.getItemName());
    });
  }
}
<!-- app.component.html -->
<app-parent>
  <app-item></app-item>
  <app-item></app-item>
  <app-item></app-item>
</app-parent>
  • @ContentChildren(ItemComponent)을 사용하여 부모가 여러 개의 자식 컴포넌트를 배열 형태로 참조합니다.
  • QueryList.forEach()를 이용해 각 자식의 getItemName()을 호출합니다.
  • 부모가 모든 자식 데이터를 한 번에 관리하고 조작할 수 있습니다.
 

 @ContentChild vs @ViewChild 차이점

 

특징 @ContentChild / @ContentChildren @ViewChild / @ViewChildren
대상 ng-content로 전달된 자식 요소 부모의 템플릿 내 요소
접근 가능 시점 ngAfterContentInit 이후 ngAfterViewInit 이후
다중 요소 관리 @ContentChildren 사용 @ViewChildren 사용
  • @ViewChild@ViewChildren은 부모 템플릿에서 선언된 요소를 다룹니다.
  • @ContentChild@ContentChildrenng-content로 삽입된 외부 요소를 다룹니다.

부모가 자식의 상태 변경 감지하기

자식이 부모에게 변경 사항 알리기

자식이 @Output()을 사용하여 부모에게 상태 변화를 알리는 것도 가능하지만, @ContentChild를 활용하면 더 직관적으로 부모가 자식의 변화를 감지할 수 있습니다.

// child.component.ts
import { Component, EventEmitter, Output } from '@angular/core';

@Component({
  selector: 'app-child',
  template: `<button (click)="updateState()">상태 변경</button>`
})
export class ChildComponent {
  @Output() stateChanged = new EventEmitter<string>();

  updateState() {
    this.stateChanged.emit('새로운 상태');
  }
}
// parent.component.ts
import { Component, ContentChild, AfterContentInit } from '@angular/core';
import { ChildComponent } from './child.component';

@Component({
  selector: 'app-parent',
  template: `<ng-content></ng-content>`
})
export class ParentComponent implements AfterContentInit {
  @ContentChild(ChildComponent) child!: ChildComponent;

  ngAfterContentInit() {
    this.child.stateChanged.subscribe(state => {
      console.log('자식 상태 변경:', state);
    });
  }
}
 

'개발 공부 > Angular' 카테고리의 다른 글

Angular Resolve  (0) 2025.03.15
Angular CanActivate  (0) 2025.03.13
@ViewChild와 @ViewChildren (3) ngAfterViewInit, static  (0) 2025.02.17
@ViewChild와 @ViewChildren (2) 기본 활용  (0) 2025.02.15
@ViewChild와 @ViewChildren (1)  (0) 2025.02.13