App을 구성하는 기본단위
🌟 컴포넌트의 구성은
@Component() 데코레이터는 Angular에 필요한 정보를 지정하는 역할
컴포넌트 구성하기
import { Component } from '@angular/core';
@Component({
selector: 'hello-world',
template: `
<h2>Hello World</h2>
<p>This is my first component!</p>
`
})
export class HelloWorldComponent {
// 여기에는 컴포넌트의 동작을 정의하는 코드가 들어갑니다.
}
템플릿에서 컴포넌트 사용
<hello-world></hello-world>
Angular가 컴포넌트 렌더링 한 후 DOM
<hello-world>
<h2>Hello World</h2>
<p>This is my first component!</p>
</hello-world>
Angular 컴포넌트는 강력하게 캡슐화되어 있지만 애플리케이션 구조에 맞게 직관적으로 구성
컴포넌트를 사용하면 애플리케이션에 유닛 테스트를 적용하기 쉽고, 코드의 가독성도 높일 수 있음
컴포넌트는 이 컴포넌트가 어떻게 렌더링될지 정의하기 위해 HTML 템플릿이 존재
🌟 템플릿은 인라인으로 정의하거나 별도 파일로 작성해서 불러올 수 있음
템플릿은 HTML 문법을 기본으로 작성
컴포넌트에 있는 값을 동적으로 반영하도록 구성
🌟 그래서!! 컴포넌트의 상태가 변경되면 Angular가 자동으로 렌더링된 DOM을 갱신
// 렌더링 컴포넌트의 템플릿
// 🌟 이중 중괄호 ( {{, }} )는 템플릿에 문자열을 바인딩하는 문법 (interpolation)
<p>{{ message }}</p>
// 컴포넌트 클래스에서 문자열 전달
import { Component } from '@angular/core';
@Component ({
selector: 'hello-world-interpolation',
templateUrl: './hello-world-interpolation.component.html'
})
export class HelloWorldInterpolationComponent {
message = 'Hello, World!';
}
// 애플리케이션이 로드하면 보이는 화면은
<p>Hello, World!</p>
// 🌟 대괄호 ( [, ] )는 컴포넌트 클래스에 있는 값을 property나 attribute로 바인딩하는 문법
<p
[id]="sayHelloId"
[style.color]="fontColor">
You can set my color in the component!
</p>
// 🌟 감지하려는 이벤트 이름을 소괄호 ( (, ) )로 감싸줌
<button
type="button"
[disabled]="canClick"
(click)="sayMessage()">
Trigger alert message
</button>
// 이벤트에 따라 실행될 메서드 in 컴포넌트 클래스
sayMessage() {
alert(this.message);
}
// ts 파일
import { Component } from '@angular/core';
@Component ({
selector: 'hello-world-bindings',
templateUrl: './hello-world-bindings.component.html'
})
export class HelloWorldBindingsComponent {
fontColor = 'blue';
sayHelloId = 1;
canClick = false;
message = 'Hello, World';
sayMessage() {
alert(this.message);
}
}
// html 파일
<button
type="button"
[disabled]="canClick"
(click)="sayMessage()">
Trigger alert message
</button>
<p
[id]="sayHelloId"
[style.color]="fontColor">
You can set my color in the component!
</p>
<p>My color is {{ fontColor }}</p>
// ngIf 예시
// ts 파일
import { Component } from '@angular/core';
@Component({
selector: 'hello-world-ngif',
templateUrl: './hello-world-ngif.component.html'
})
export class HelloWorldNgIfComponent {
message = "I'm read only!";
canEdit = false;
onEditClick() {
this.canEdit = !this.canEdit;
if (this.canEdit) {
this.message = 'You can edit me!';
} else {
this.message = "I'm read only!";
}
}
}
// html 파일
<h2>Hello World: ngIf!</h2>
<button type="button" (click)="onEditClick()">Make text editable!</button>
<div *ngIf="canEdit; else noEdit">
<p>You can edit the following paragraph.</p>
</div>
<ng-template #noEdit>
<p>The following paragraph is read only. Try clicking the button!</p>
</ng-template>
<p [contentEditable]="canEdit">{{ message }}</p>
// logger.service.ts
// 인자로 받은 숫자 콘솔 출력 함수 정의
import { Injectable } from '@angular/core';
@Injectable({providedIn: 'root'})
export class Logger {
writeCount(count: number) {
console.warn(count);
}
}
// hello-world-di.component.ts
// angular 컴포넌트
// 버튼 클릭시 Logger 클래스 writeCount 함수 실행
// 어떻게? => 클래스 생성자에 logger 코드 추가해서 Logger 서비스가 의존성 객체로 주입되도록 요청
import { Component } from '@angular/core';
import { Logger } from '../logger.service';
@Component({
selector: 'hello-world-di',
templateUrl: './hello-world-di.component.html'
})
export class HelloWorldDependencyInjectionComponent {
count = 0;
constructor(private logger: Logger) { }
onLogMe() {
this.logger.writeCount(this.count);
this.count++;
}
}