본문 바로가기
개인공부/Angular

Angular란?

by 왕큰새 2022. 3. 6.
728x90

Angular란?

TypeScript를 기반으로 개발된 개발 플랫폼

  • 확장가능한 컴포넌트 구조로 웹 애플리케이션을 만드는 프레임워크
  • 라우팅, 폼 관리, 클라이언트-서버 통신 등 웹 개발에 필요한 라이브러리를 통합한 모음집
  • 애플리케이션 개발, 빌드, 테스트, 수정에 필요한 개발자 도구를 제공한다

라고 Angular 공식 문서에 적혀있다.

 


Angular 기초 

컴포넌트(Component) - 애플리케이션을 구성하는 기본 단위

@Component 데코레이터(Decorator)가 붙는 TypeScript Class, HTML Template, Style로 구성된다.

 

Decorator? Java에서의 Annotation과 유사하게 메타데이터를 지정할 수 있다.

다른 점은 메소드나 프로퍼티를 직접 변경할 수 있다는 점이 다른점

함수를 파라미터로 받는 함수를 쉽게 선언하는 일종의 Sugar Syntax라고 한다.

정확하지 않을 수 있으니 궁금하면 직접 더 찾아보시길...

 

 

다음과 같이 Angular에 필요한 정보를 지정하는 역할을 한다.

  • 컴포넌트가 템플릿에 사용될 CSS 셀렉터를 지정한다. 템플릿에서 이 셀렉터에 해당되는 HTML 엘리먼트마다 컴포넌트 인스턴스가 생성된다.
  • Angular가 컴포넌트 내용으로 렌더링할 HTML 템플릿을 지정한다.
  • 템플릿 HTML 엘리먼트의 모습을 지정해야 한다면 필요한 CSS 스타일을 지정한다.

 

기본 내용만 담아 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이 이렇게 된다.

 

렌더링 : HTML, CSS, JavaScript 등 개발자가 작성한 문서를 브라우저에서 그래픽 형태로 출력하는 과정

DOM(Document Object Model) : 문서 객체 모델 - 번역만으로는 무슨 말인지 감이 안옴

문서 객체란?
<html>이나 <body> 같은 html 문서의 태그들을 JavaScript가 이용할 수 있는 객체로 만든 것

모델이란?
인식하는 방식 

넓은 의미의 DOM : 웹 브라우저가 HTML 페이지를 인식하는 방식
좁은 의미의 DOM : document 객체와 관련된 객체의 집합
<hello-world>
    <h2>Hello World</h2>
    <p>This is my first component!</p>
</hello-world>

 

 

Angular 컴포넌트는 강력하게 캡슐화되어 있지만, 애플리케이션 구조에 맞게 직관적으로 구성된다고 한다.

컴포넌트를 사용하면, 애플리케이션에 유닛 테스트를 적용하기 쉽고, 코드의 가독성도 높일 수 있다.

 


템플릿(Templates)

HTML 문법을 기본으로 작성하며, 컴포넌트에 있는 값을 동적으로 반영하도록 구성

컴포넌트의 상태가 변경되면 Angular가 자동으로 렌더링된 DOM을 갱신

 

문자열을 동적으로 렌더링하는 컴포넌트의 템플릿 코드

 

<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>

 

템플릿에 이중 중괄호가 사용된 것을 확인할 수 있다. ( {{, }} ) 템플릿에 문자열을 바인딩(interpolation) 하는 문법이다.

 

문자열 바인딩 외에도, HTML 엘리먼트의 프로퍼티나 어트리뷰트에 값을 할당하는

프로퍼티 바인딩(property binding)문법도 제공 한다.

 

<p
  [id]="sayHelloId"
  [style.color]="fontColor">
  You can set my color in the component!
</p>

 

대괄호가 사용된 것을 확인 할 수 있다. 컴포넌트에 있는 값을 프로퍼티나 어트리뷰트로 바인딩 하는 문법이다.

 

키입력, 마우스 이동, 클릭, 터치 등과 같은 이벤트를 감지하고, 이벤트 리스너를 추가할 수도 있다. 

이 문법은 소괄호로 감싸면된다.

<button
  [disabled]="canClick"
  (click)="sayMessage()">
  Trigger alert message
</button>

 

 

아래의 예제를 보면서, 문자열 바인딩, 프로퍼티 바인딩, 이벤트 바인딩이 어떻게 사용되는지 확인해보자.

 

hello-world-bindings.component.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);
  }
 
}

 

hello-world-bindings.component.html

<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>

 

선언적인 템플릿 문법을 사용하기 때문에 화면에 표시되는 단위로 애플리케이션 로직을 깔끔하게 분리할 수 있다.

 

표준 HTML 문법을 활용하기 때문에 구성하기 쉽고, 관리하기 쉬우며, 나중에 수정하기도 쉽다.


의존성 주입(Dependency injection, DI) 

의존성 주입이란? - 필요한 객체를 직접 생성하는 것이 아닌 외부로부터 필요한 객체를 받아서 사용하는 것

장점 - 객체 간 결합도 감소, 코드의 재활용성 증가

 

Angular는 TypeScript 클래스를 활용하는 의존성 주입 시스템을 제공한다.

Angular 애플리케이션을 개발할 때 의존성 주입 시스템을 반드시 알아야 하는 것은 아니지만,

의존성 주입을 사용하였을 때, 얻는 장점을 위하여 적극 권장!!!

 

간단한 예제로 의존성 주입을 확인해보자.

 

import { Injectable } from '@angular/core';

@Injectable({providedIn: 'root'})
export class Logger {
  writeCount(count: number) {
    console.warn(count);
  }
}

Logger 클래스가 정의되어 있고, 인자로 받은 숫자를 콘솔에 출력하는 writeCount 함수가 정의되어 있다.

 

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++;
  }
}

위의 컴포넌트에는 버튼이 하나 있는데, 이 버튼을 클릭하면 Logger 클래스에 있는 writeCount 함수를 실행하려고 한다.

 

클래스 생성자에 private logger: Logger라는 코드를 추가해서 Logger 클래스를 의존성 객체로 주입할 수 있다.