자식 구성 요소, 지시문 또는 DOM 요소에 액세스하기 위해 Angular에서 ViewChild를 사용하는 방법


소개

이 기사에서는 Angular의 ViewChild 데코레이터를 소개합니다.

부모 구성 요소 클래스에서 지시문, 자식 구성 요소 또는 DOM 요소에 액세스하려는 상황이 있을 수 있습니다. ViewChild 데코레이터는 지정된 지시문, 구성 요소 또는 템플릿 참조 선택기와 일치하는 첫 번째 요소를 반환합니다.

전제 조건

이 튜토리얼을 따라하고 싶다면:

  • @angular/cli 설치를 고려하세요.
  • @angular/cli를 사용하여 ViewChild 기능을 테스트할 새 프로젝트를 만듭니다.

이 튜토리얼은 @angular/core v13.0.2 및 @angular/cli v13.0.3에서 확인되었습니다.

지시문과 함께 ViewChild 사용

ViewChild를 사용하면 지시문에 액세스할 수 있습니다.

SharkDirective가 있다고 가정해 보겠습니다. 이 지시문은 appShark 속성이 있는 요소를 찾고 요소의 텍스트 앞에 Shark라는 단어를 붙입니다.

이상적으로는 @angular/cli를 사용하여 지시문을 생성합니다.

  1. ng generate directive shark --skip-tests

이 명령은 shark.directive.ts 파일을 생성합니다. 그리고 app.module.ts에 지시문을 추가합니다.

import { SharkDirective } from './shark.directive';
...
@NgModule({
  declarations: [
    AppComponent,
    SharkDirective
  ],
  ...
})

그런 다음 ElementRefRenderer2를 사용하여 텍스트를 다시 작성합니다. shark.directive.ts의 내용을 다음으로 바꿉니다.

import {
  Directive,
  ElementRef,
  Renderer2
} from '@angular/core';

@Directive(
  { selector: '[appShark]' }
)
export class SharkDirective {
  creature = 'Dolphin';

  constructor(elem: ElementRef, renderer: Renderer2) {
    let shark = renderer.createText('Shark ');
    renderer.appendChild(elem.nativeElement, shark);
  }
}

다음으로 구성 요소 템플릿의 텍스트를 포함하는 spanappShark 특성을 추가합니다. app.component.html의 내용을 다음으로 바꿉니다.

<span appShark>Fin!</span>

브라우저에서 애플리케이션을 볼 때 요소의 내용 앞에 \Shark\라는 단어가 렌더링됩니다.

Output
Shark Fin!

이제 SharkDirectivecreature 인스턴스 변수에 액세스하고 해당 값으로 extraCreature 인스턴스 변수를 설정할 수도 있습니다. app.component.ts의 내용을 다음으로 바꿉니다.

import {
  Component,
  ViewChild,
  AfterViewInit
} from '@angular/core';
import { SharkDirective } from './shark.directive';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
  extraCreature!: string;

  @ViewChild(SharkDirective)
  set appShark(directive: SharkDirective) {
    this.extraCreature = directive.creature;
  };

  ngAfterViewInit() {
    console.log(this.extraCreature); // Dolphin
  }
}

이 코드는 setter를 사용하여 extraCreature 변수를 설정했습니다. AfterViewInit 수명 주기 후크가 변수에 액세스할 때까지 기다립니다. 이 때 하위 구성 요소와 지시문을 사용할 수 있게 됩니다.

브라우저에서 애플리케이션을 볼 때 여전히 \Shark Fin!\ 메시지가 표시됩니다. 그러나 콘솔 로그에는 다음과 같이 표시됩니다.

Output
Dolphin

부모 구성 요소가 지시문의 값에 액세스할 수 있었습니다.

DOM 요소와 함께 ViewChild 사용

ViewChild를 사용하면 템플릿 참조 변수가 있는 기본 DOM 요소에 액세스할 수 있습니다.

템플릿에 #someInput 참조 변수가 있는 가 있다고 가정해 보겠습니다. app.component.html의 내용을 다음으로 바꿉니다.

<input #someInput placeholder="Your favorite sea creature">

이제 ViewChild에 액세스하고 value를 설정할 수 있습니다. app.component.ts의 내용을 다음으로 바꿉니다.

import {
  Component,
  ViewChild,
  AfterViewInit,
  ElementRef
} from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
  @ViewChild('someInput') someInput!: ElementRef;
  ngAfterViewInit() {
    this.someInput.nativeElement.value = 'Whale!';
  }
}

ngAfterViewInit가 실행되면 의 값은 다음과 같이 설정됩니다.

Output
Whale!

부모 구성 요소가 자식 DOM 요소의 값을 설정할 수 있었습니다.

자식 구성 요소와 함께 ViewChild 사용

ViewChild는 자식 구성 요소에 액세스하고 메서드를 호출하거나 자식이 사용할 수 있는 인스턴스 변수에 액세스할 수 있도록 합니다.

PupComponent가 있다고 가정해 보겠습니다.

이상적으로는 @angular/cli를 사용하여 구성 요소를 생성합니다.

  1. ng generate component pup --flat --skip-tests

이 명령은 pup.component.ts, pup.component.csspup.component.html 파일을 생성합니다. 그리고 구성 요소를 app.module.ts에 추가합니다.

import { PupComponent } from './pup.component';
...
@NgModule({
  declarations: [
    AppComponent,
    PupComponent
  ],
  ...
})

그런 다음 메시지를 반환하는 whoAmI 메서드를 PupComponent에 추가합니다.

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-pup',
  templateUrl: './pup.component.html',
  styleUrs: ['./pup/component.css']
})
export class PupComponent implements OnInit {

  constructor() { }

  whoAmI() {
    return 'I am a pup component!';
  }

  ngOnInit(): void {
  }

}

다음으로 앱 템플릿에서 자식 구성 요소를 참조합니다. app.component.html의 내용을 다음으로 바꿉니다.

<app-pup>pup works!</app-pup>

이제 ViewChild를 사용하여 부모 구성 요소 클래스 내에서 whoAmI 메서드를 호출할 수 있습니다. app.component.ts의 내용을 다음으로 바꿉니다.

import {
  Component,
  ViewChild,
  AfterViewInit
} from '@angular/core';
import { PupComponent } from './pup.component';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements AfterViewInit {
  @ViewChild(PupComponent) pup!: PupComponent;
  ngAfterViewInit() {
    console.log(this.pup.whoAmI()); // I am a pup component!
  }
}

브라우저에서 애플리케이션을 볼 때 콘솔 로그에 다음이 표시됩니다.

Output
I am a pup component!

부모 구성 요소는 자식 구성 요소의 whoAmI 메서드를 호출할 수 있었습니다.

결론

이 자습서에서는 ViewChild를 사용하여 지시문, 자식 구성 요소 및 부모 구성 요소 클래스의 DOM 요소에 액세스했습니다.

참조가 새 요소로 동적으로 변경되면 ViewChild는 해당 참조를 자동으로 업데이트합니다.

여러 자식에 액세스하려는 경우 대신 ViewChildren을 사용합니다.

Angular에 대해 자세히 알아보려면 연습 및 프로그래밍 프로젝트에 대한 Angular 주제 페이지를 확인하십시오.