console.log("연록")

[Angular] Angular 시작하기 - (2) 자식, 부모 컴포넌트에 데이터 전달하기 본문

bone up/Angular

[Angular] Angular 시작하기 - (2) 자식, 부모 컴포넌트에 데이터 전달하기

연 록 2022. 3. 15. 14:31
728x90

https://angular.kr/start#%EC%9E%90%EC%8B%9D-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EB%A1%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EB%8B%AC%ED%95%98%EA%B8%B0

 

Angular 가이드

Angular 가이드

angular.kr


자식 컴포넌트로 데이터 전달하기

 

ProductListComponent에 있는 상품 데이터를 활용해 알림 구현

→ 상품의 가격이 $700 이상이면 Notify Me 버튼을 표시해 해당 상품이 세일 진행시 사용자에게 알림

 

 부모 컴포넌트 ProductListComponent에서 데이터를 받는 자식 컴포넌트 ProductAlertsComponent를 만들기

 

 

1. app 폴더 우클릭 후 Angular Generator 선택하여 product-alerts라는 이름의 Component(컴포넌트) 생성

 

그러면 컴포넌트를 구성하는 다음 3개 파일이 생성

  • product-alerts.component.ts
  • product-alerts.component.html
  • product-alerts.component.css

 

2.  ProdcutAlertsComponent가 상품 데이터를 받을 수 있도록 @angular/core 패키지가 제공하는 Input 심볼 product-alerts.component.ts에 로드

 

(Input 로드하기 전에)

* product-alerts.component.ts 파일

@Component( ) 데코레이터

이 데코레이터가 붙은 클래스가 컴포넌트라는 것을 지정하는 용도

컴포넌트 셀렉터(selector), 템플릿(templateUrl), 스타일(styleUrls)에 해당하는 메타데이터 지정 가능

 

@Component( ) 데코레이터에서 중요한 것

  • app-product-alerts라는 selector는 이 컴포넌트가 어떤 태그 이름으로 사용될지 결정. 보통 Angular 컴포넌트는 app-이라는 접두사로 시작하고 그 뒤에 컴포넌트 이름을 붙임
  • 컴포넌트에 사용될 HTML 파일과 CSS 파일을 지정
  • @Component( ) 데코레이터 뒤에는 컴포넌트의 동작을 정의할 클래스를 ProductAlertsComponent와 같이 선언

 

 

3. ProductAlertsComponent 클래스 선언에 product라는 프로퍼티를 선언하고 이 프로퍼티 앞에 @Input( ) 데코레이터 지정

프로퍼티에 @Input( ) 데코레이터를 지정하면 해당 프로퍼티의 값을 부모 컴포넌트에서 받아온다는 것을 의미

이 경우에는 ProductListComponent가 부모 컴포넌트(5번 참조)

 

4. product-alerts.component.html 파일을 상품의 가격이 $700을 넘으면 Notify Me 버튼을 표시하도록 수정

 

5. app.module.ts에 import { ProductAlertsComponent } from './product-alerts/product-alerts.component';와 @NgModule 아래의 declarations에 ProductAlertsComponent를 추가

 

app.module.ts는 src/app/app.module.ts에 위치

 

(이 부분이 한국어 문서에는 제대로 기술되어 있지 않았고 영어 문서에는 자동으로 추가된다고 서술되어 있어 잘 이해가 안 갔다. 선임님께 여쭈어 보니 보통 앵귤러는 명령어를 통해 이런 import를 시킨다고 한다. 그러나 Stackblitz의 Angular는 terminal을 제공하지 않아 직접 입력을 해야하고 영어 문서의 경우 terminal을 사용하는 걸 전제로 해서 automatically add 된다고 한 거였다.)

 

6. ProductListComponent의 자식 컴포넌트로 ProductAlertsComponent를 표시하기 위해 product-list.component.html 파일에 <app-product-alerts> 셀렉터를 추가

 

프로퍼티 바인딩을 통해 해당 상품이 자식 컴포넌트의 입력 프로퍼티로 전달


~여기까지 결과~

Phone XL만 가격이 $700이상이기때문에 얘만 Notify Me 버튼이 표시됨


부모 컴포넌트로 데이터 전달하기

 

Notify Me 버튼이 제대로 동작하려면 자식 컴포넌트에서 부모 컴포넌트로 데이터를 전달해 알림을 보내야 함

ProductAlertsComponent는 사용자가 Notify Me 버튼을 클릭했을 때 부모 컴포넌트로 이벤트를 보내야 함

 

Angular Generator로 컴포넌트를 새로 만들면 constructor( ) 메서드가 빈 내용으로 생성되며, OnInit 인터페이스를 확장하는 ngOnInit( ) 메서드도 함께 생성
지금 단계에서는 이 메서드들을 사용하지 않기 때문에 예제에서 생략

 

1. product-alert.component.ts  파일에 @angular/core 패키지가 제공하는 Output 심볼과 EventEmitter 심볼 로드

문서에는 OnInit이 없는데 앞에 말한대로 OnInit은 사용하지 않아 지움

 

2. 컴포먼트 클래스에 notify 프로퍼티를 추가하고 이 프로퍼티에 @Output( ) 데코레이터를 지정 후 EventEmitter( ) 인스턴스 할당

문서와 다른 부분은 아래▼를 보면 이해 가능

Angular Generator로 컴포넌트를 새로 만들면 constructor() 메서드가 빈 내용으로 생성되며, OnInit 인터페이스를 확장하는 ngOnInit() 메서드도 함께 생성
지금 단계에서는 이 메서드들을 사용하지 않기 때문에 예제에서 생략

 

3. product-alerts.component.html 파일에 있는 Notify Me 버튼에 이벤트 바인딩을 연결해서 (click) 이벤트가 발생하면 notify.emit() 메서드를 실행하게 함

 

4. 사용자가 버튼을 클릭했을 때 필요한 동작을 구현

→ 자식 컴포넌트에서 발생한 이벤트는 자식 컴포넌트 ProductALertsComponent가 아니라 부모 컴포넌트 ProductListComponent에서 처리해야 함

product-list.component.ts 파일을 열고 onNotify( ) 메서드 추가(이 메서드의 내용은 share( )와 비슷)

 

5. ProductAlertsComponent가 보낸 데이터를 ProductListComponent가 받을 수 있도록 수정

product-list.component.html 파일의 <app-product-alerts>onNotify( ) 메서드 바인딩

<app-product-alerts>는 Notify Me가 표시되는 버튼

 


~결과~

 

 

StackBlitz 말고 로컬에서도 작업해봐야겠다