[2019.07.15] TypeScript와 앵귤러(3)

[2019.07.15] TypeScript와 앵귤러(3)

https://angular.kr/start

템플릿 문법

*ngFor 디렉티브 : 에 *ngFor를 사용하면 목록에 있는 제품마다 같은 템플릿을 반복할 수 있음.

예 ) 하면 모든 products의 각 product에 대하여 같은 템플릿을 반복 할 수 있다.

구조 디렉티브 : *으로 시작하는 디렉티브는 모두 구조 디렉티브. 일반적으로 엘리먼트를 추가하거나 제거하고, 변형하는 방식으로 DOM 구조를 구성하는 디렉티브이다.

문자열 바인딩 문법 : {{ }} 으로 감싸면 프로퍼티 값을 문자열로 표시(렌더링)할 수 있다.

프로퍼티 바인딩 문법 : [ ] 으로 감싸면 프로퍼티 값을 바인딩하는 템플릿 표현식을 정의할 수 있다.

이벤트 바인딩 문법 : 이벤트 이름을 ( ) 으로 감싼다.

컴포넌트(Component)

컴포넌트란? 특정 UI 영역을 재사용하기 위해 따로 분리해서 정의한 것.

컴포넌트의 구성요소 3가지 : 컴포넌트 클래스, HTML 템플릿, 컴포넌트 스타일

- 컴포넌트 클래스 : 데이터를 처리하는 로직과 같은 컴포넌트의 동작을 담당. 제품 데이터나 share()메소드 등이 정의되어 있는 곳

- HTML 템플릿 : 사용자에게 표시되는 화면을 정의. 이전까지 화면을 수정한 것들이 HTML 템플릿을 수정한 것임.

- 컴포넌트 스타일 : HTML 템플릿의 모양을 정의

입력 프로퍼티

하고 싶은 것 : 제품 가격이 $700 이상이면 "Notify Me" 버튼을 표시. 버튼을 누르면 회원가입 화면 제공.

product-alerts라는 이름의 새로운 컴포넌트를 생성 -> ts, html, css 3개의 파일이 생성되는데

product-alerts.component.ts를 연다.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import { Component, OnInit } from '@angular/core' ; import { Input } from '@angular/core' ; //새로 만든 컴포넌트가 제품 정보를 입력 프로퍼티로 받도록 설정(@angular/core 에서 Input 심볼을 로드) @Component({ //@Component 데코레이터 : 아래의 클래스가 컴포넌트라는 것을 지정하는 데코레이터. 컴포넌트와 관련된 메타데이터를 인자로 받는다. selector: 'app-product-alerts' , //컴포넌트를 구분하는 id. 나중에 HTML이 렌더링될 때 이 셀렉터가 사용된 곳에 셀렉터에 해당되는 Angular 컴포넌트가 들어간다. templateUrl: './product-alerts.component.html' , styleUrls: [ './product-alerts.component.css' ] }) export class ProductAlertsComponent implements OnInit { //컴포넌트의 동작을 처리하는 클래스 @Input() product; //product 프로퍼티를 선언 -> 이 프로퍼티에 @Input 데코레이터를 지정. (product 프로퍼티에 할당되는 값이 부모 컴포넌트(이 예제에서는 제품 목록 컴포넌트)에서 전달된다는 것을 의미) constructor() { } ngOnInit() { } } Colored by Color Scripter cs

수정한 후 product-alerts.component.html 템플릿 파일을 열어 수정한다.

1 2 3 < p * ngIf = "product.price > 700" > < button > Notify Me < / button > < / p > cs 이렇게 하면 Notify Me 버튼 사용 준비 완료.

product-list.component.html 을 열어 아래와 같이 수정하면 700 이상인 제품에 한해 버튼이 나타난다.

1 2 3 4 < ! - - 새로운 컴포넌트를 추가하기 위해 이 컴포넌트에 지정한 app - product - alert 셀렉터를 HTML 엘리먼트인 것처럼 추가 - - > < app - product - alerts [product] = "product" > < ! - - 현재 * ngFor 루프에 해당하는 제품 정보를 프로퍼티 바인딩 문법으로 자식 컴포넌트에 전달 - - > < / app - product - alerts > Colored by Color Scripter cs

출력 프로퍼티

하고 싶은 것 : Notify Me버튼을 클릭했을 때 제품 목록 컴포넌트로 이벤트를 보내도록 구현.

1. product-alerts.component.ts 파일을 연다.

2. @angular/core 에서 Output과 EventEmitter 심볼을 로드.

3. 이 컴포넌트 클래스에서 컴포넌트 밖으로 이벤트를 보낼 notify 프로퍼티를 정의하고, 이 프로퍼티에 @Output 데코레이터를 지정.

4. 템플릿 파일(product-alerts.component.html)의 "Notify Me" 버튼이 notify.emit() 메소드를 실행하도록 이벤트를 바인딩.

5. 버튼이 클릭되었을 때 동작할 로직을 작성. 이 로직은 제품할인 알림 컴포넌트가 아니라 부모 컴포넌트인 제품 목록 컴포넌트에 작성한다. product-list.component.ts 파일에 onNotify() 메소드를 정의.

6. 제품할인 알림 컴포넌트에서 발생하는 이벤트를 제품 목록 컴포넌트가 받을 수 있도록 제품 목록 컴포넌트의 템플릿을 수정한다. app-product-alerts 컴포넌트가 보내는 notify 이벤트를 제품 목록 컴포넌트가 받으면 onNotify() 메소드를 실행하도록 product-list.component.html 파일을 수정.

최종

1 2 3 4 5 < app-top-bar > < / app-top-bar > < div class = "container" > < router-outlet > < / router-outlet > < / div > cs ↑ app.component.html

1 2 3 4 5 6 7 8 import { Component } from '@angular/core' ; @Component({ selector: 'app-root' , templateUrl: './app.component.html' , styleUrls: [ './app.component.css' ] }) export class AppComponent {} cs ↑ app.component.ts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 export const products = [ { name : 'Phone XL' , price: 799 , description: 'A large phone with one of the best screens' }, { name : 'Phone Mini' , price: 699 , description: 'A great phone with one of the best cameras' }, { name : 'Phone Standard' , price: 299 , description: '' } ]; Colored by Color Scripter cs ↑ products.ts

1 2 3 4 5 < a [routerLink] = "['/']" > < h1 > My Store < / h1 > < / a > < a [routerLink] = "['/cart']" class = "button fancy-button" > < i class = "material-icons" > shopping_cart < / i > Checkout < / a > cs ↑ top-bar.component.html

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import { Component, OnInit } from '@angular/core' ; @Component({ selector: 'app-top-bar' , templateUrl: './top-bar.component.html' , styleUrls: [ './top-bar.component.css' ] }) export class TopBarComponent implements OnInit { constructor() { } ngOnInit() { } } Colored by Color Scripter cs ↑ top-bar.component.ts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 < h2 > Products < / h2 > < div *ngFor = 'let product of products' > < h3 > < a [title] = "product.name + ' details'" > {{product.name}} < / a > < / h3 > < p *ngIf = "product.description" > Description: {{product.description}} < / p > < button (click) = "share()" > Share < / button > < app-product-alerts [product] = "product" (notify) = "onNotify()" > < / app-product-alerts > < / div > Colored by Color Scripter cs ↑ product-list.component.html

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import { Component } from '@angular/core' ; import { products } from '../products' ; @Component({ selector: 'app-product-list' , templateUrl: './product-list.component.html' , styleUrls: [ './product-list.component.css' ] }) export class ProductListComponent { products = products; share() { window . alert ( 'The product has been shared!' ); } onNotify(){ //버튼이 클릭되었을 때 동작할 로직 window . alert ( 'You will be notified when the product goes on sale' ); } } Colored by Color Scripter cs ↑ product-list.component.ts

1 2 3 < p *ngIf = "product.price > 700" > < button (click) = "notify.emit()" > Notify Me < / button > < / p > Colored by Color Scripter cs ↑ product-alerts.component.html

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import { Component, OnInit } from '@angular/core' ; import { Input } from '@angular/core' ; //새로 만든 컴포넌트가 제품 정보를 입력 프로퍼티로 받도록 설정(@angular/core 에서 Input 심볼을 로드) import { Output, EventEmitter } from '@angular/core' ; @Component({ //@Component 데코레이터 : 아래의 클래스가 컴포넌트라는 것을 지정하는 데코레이터. 컴포넌트와 관련된 메타데이터를 인자로 받는다. selector: 'app-product-alerts' , //컴포넌트를 구분하는 id. 나중에 HTML이 렌더링될 때 이 셀렉터가 사용된 곳에 셀렉터에 해당되는 Angular 컴포넌트가 들어간다. templateUrl: './product-alerts.component.html' , styleUrls: [ './product-alerts.component.css' ] }) export class ProductAlertsComponent implements OnInit { //컴포넌트의 동작을 처리하는 클래스 @Input() product; //product 프로퍼티를 선언 -> 이 프로퍼티에 @Input 데코레이터를 지정. (product 프로퍼티에 할당되는 값이 부모 컴포넌트(이 예제에서는 제품 목록 컴포넌트)에서 전달된다는 것을 의미) @Output() notify = new EventEmitter(); //이 컴포넌트 클래스에서 컴포넌트 밖으로 이벤트를 보낼 notify 프로퍼티. @Output 데코레이터를 지정하면 제품할인 컴포넌트에서 이벤트를 보낼 수 있음 constructor() { } ngOnInit() { } } Colored by Color Scripter cs

↑ product-alerts.component.ts

from http://junodiary.tistory.com/61 by ccl(A) rewrite - 2020-04-02 14:27:12