ARCHITECTURE OVERVIEW
Angular 앱의 기본 요소
Angular는 HTML와 JavaScript 또는 JavaScript로 컴파일 되는 TypeScript와 같은 언어로 클라이언트 앱을 만드는 프레임워크이다.
프레임워크는 몇몇은 코어, 몇몇은 선택적으로 사용가능한 라이브러리들로 이뤄져 있다.
Angular 마크업이 있는 HTML템플릿과 템플릿을 관리하는 컴포넌트 클래스, 서비스의 추가적인 앱 로직, 컴포넌트와 서비스를 포함하고 있는 모 듈로 Angular 앱을 작성한다.
(Angular 앱은 템플릿, 컴포넌트, 서비스 그리고 모듈로 이뤄져 있다.)
root 모듈을 부트스트랩해 앱을 실행한다. Angular은 브라우저에 앱의 콘텐츠를 보여주고 사용자와 상호작용 한다.
물론 이 것 이외의 내용도 있다. 자세한 내용은 이 문서에서 다룰 것이다. 지금은 큰 그림에 주목하자.

구조에 대한 그림은 Angular 앱의 8개의 주요 구성요소를 보여준다:
위의 구성요소들에 대해서 알아볼 것이다.
이 문서에서 참조하는 코드는 live example / 다운로드 가능한 예제 이다.
Modules

Angular 앱은 모듈로 이뤄져 있으면 Angular는 Angular 모듈 또는 NgModule이라고 불리는 모듈화 시스템을 가지고 있다.
Angular Module은 다룰 내용이 많다. 여기서는 단지 모듈에 대해서 소개만 한다. Angular Modules 페이지에서 좀더 자세하게 다룰 것이다.
모든 Angular 앱은 최소한 하나의 모듈 클래스 the root module를 가지며 편의상 이름을 AppModule이라고 한다.
작은 앱은 root 하나로 이뤄진 반면 대부분의 앱은 많은 기능 모듈로 이뤄져 있다.
루트 또는 기능 하나의 Angular 모듈은 은 @NgModule 데코레이터를 가지는 클래스이다.
데코레이터는 JavaScript 클래스들을 변경하는 함수이다. Angular는 클래스에 메타데이터를 추가해 클래스가 어떠한 의미를 가지고 어떻게 동작하는지 알려주는 많은 데코레이터를 가지고 있다. 웹에 데코레이터에 대에서 더 많은 내용들이 있다.
NgModule은 모듈에 대한 속성을 가지고 있는 하나 메타데이터 객체를 가지는 데코레이터 함수이다. 중요한 속성들은 다음과 같다:
declarations - 모듈에 포함되는 뷰 클래스들이다. Angular는 3가지의 뷰클래스들을 가지고 있다: 컴포넌트, 디렉티브, 파이
exports - 다른 모듈의 컴포넌트 템플릿에서 접근해 사용가능한 declarations의 뷰클래스들의 부분집합이다.
imports - export한 클래스들 현재 모듈의 컴포넌트 템플릿에서 필요한 다른 모듈들
providers - 서비스의 전역 집합을 제공하는 서비스들의 생성자 이다;서비스들은 앱의 모든 부분에서 접근이 가능하게 된다.
bootstrap - 루트 컴포넌트라고 불리는 앱의 첫 화면이다. 다른 화면들을 가지고 있다. 오직 루트 모듈만 bootstrap 속성에 설정한다.
아래는 간단한 root 모듈 이다:
src/app/app.modules.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
imports: [ BrowserModule ],
providers: [ Logger ],
declarations: [ AppComponent ],
exports: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule {}
AppCompnent의 export는 어떻게 내보내기를 하는지 보여주기 위해서 한 것이다; 실제로 예제서 내보내기는 필요가 없다. 루트 모듈은 다른 컴폰넌트에서 이 모듈을 가져오기를 할 필요가 없기 때문에 어떤것도 내보내기를 할 필요가 없다.
루트모듈을 부트스트랩해 앱을 실행시킨다. 개발동안 다음 예제처럼 main.ts에서 AppModule을 부트스트랩 할 것이다:
src/main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
Angular modules vs. JavaScript modules
클래스가 @NgModule데코레이터로 표현되는 Angular 모듈은 Angular의 기본적인 기능이다.
JavaScript는 JavaScript 객체의 집합을 관리하기 위한 모듈 시스템이 존재한다. JavaScript 모듈 시스템은 Angular 모듈 시스템과 전혀 다르며 관련도 없다.
JavaScript에서 각각의 파일은 모듈이며 모든 객체들은 자신이 속해 있는 파일에 정의돼 있다. 모듈들 export 키워드로 일부 객체들을 외부에 공개한다. 다른 JavaScript 모듈은 import 문을 사용해 다른 모듈이 외부에 공개한 객체들에 접근한다.
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
export class AppModule {}
인터넷에서 JavaScript 모듈에 대해서 좀더 알아 볼 수 있다.
이 두개의 다르지만 보완하는 모듈 시스템이 있다. 이 두개를 사용해 앱을 작성한다.
Angular libraries

Angular는 JavaScript 모듈의 집합이. Angular를 모듈 라이브러리라고 생각할 수 있다.
각각의 Angular 라이브러리 이름은 @angular 접두어로 시작한다.
npm 패키지 관리자로 Angular 라이브러리를 설치하고 JavaScript import 문으로 가져올 수 있다.
예를들어, Angular의 컴포넌트 데코레이터를 @angular/core 라이브러리에서 가져온다:
import { Component } from '@angular/core';
JavaScript import 구문으로 또한 Angular 라이브러리들에서 Angular 모듈들을 가져올 수 있다:
import { BrowserModule } from '@angular/platform-browser';
위의 간단한 루트 모듈예제에서, 앱 모듈은 BrowserModule 내부의 객체들가 필요할 수 있다. 내부의 내용들을 사용하기 위해서 @NgModule 메타데이터에 다음과 같이 imports를 작성 할 수 있다:
imports: [ BrowserModule ],
위의 방법으로 Angular와 JavaScript 모듈 시스템을 같이 사용할 수 있다.
같은 "import"와 "export"를 사용하기 때문에 두개의 시스템을 쉽게 혼동한다. 시간과 경험으로 이러한 혼동은 명확해 질 것 이다.
더 자세한 내용은 Angular 모듈 페이지를 참고하면 된다.
Components

컴포넌트는 화면의 뷰라고 불리는 부분을 제어한다.
예를들어, 다음 뷰는 컴포넌트에 의해서 제어된다.
- 네비게이션 링크를 가지고 있는 앱의 기본 화면
- 히어로 리스트
- 히어로 에디터
클래스 안에 컴포넌트의 앱 로직- 뷰를 어떻게 제어할지 을 정의할 수 있다. 클래스는 메소드와 속성의 API로 뷰와 상호작용한다.
예를들어 HeroListComponent는 서비스로 부터 얻어지는 히어로를 반환하는 heroes 속성을 가지고 있다. 또한 사용자가 리스트에서 히어로를 선택해 클릭했을 때, selectedHero 속성을 설정한는 selectHero() 메서드도 있다.
src/app/hero-list.component.ts (class)
export class HeroListComponent implements OnInit {
heroes: Hero[];
selectedHero: Hero;
constructor(private service: HeroService){ }
ngOnInit() {
this.heroes = this.service.getHeroes();
}
selectHero(hero: Hero) { this.selectedHero = hero; }
}
Angular는 사용자가 앱을 돌아다닐 때 생성, 업데이트, 제거된다. 앱은 위에서 선언한 ngOnInit()처럼 lifecycle hooks에서 선택해 각 순간에 취할 동작을 정의할 수 있다.
Templates

컴포넌트의 뷰는 컴포넌트의 템플릿으로 정의한다. 템플릿은 Angular에게 컴포넌트가 어떻게 보여질지 알려주는 HTML 형태이다.
템플릿은 몇가지 다른점을 빼곤 일반적인 HTML처럼 보인다. 다음은 HeroListComponet에 대한 템플릿이다.
src/app/hero-list.component.html
<h2>Hero List</h2>
<p><i>Pick a hero from the list</i></p>
<ul>
<li *ngFor="let hero of heroes" (click)="selectHero(hero)">
{{hero.name}}
</li>
</ul>
<hero-detail *ngIf="selectedHero" [hero]="selectedHero"></hero-detail>
템플릿은
,
와 같은 일반적인 HTML 요소들을 사용하지만 다른 것들도 있다. *ngFor, , (click), [hero],
템플릿의 마지막 줄
HeroDetailComponent는 우리가 봤던 HeroListComponent와 다른 컴포넌트이다. (코드엔 없는) HeroDetailComponent 사용자가 HeroListComponent에서 나타난 리스트에서 선택한 특정 히어로의 자세한 내용을 보여준다. HeroDetailComponent는 HeroListComponent의 자식이다.

<hero-detail> 가 나머지 HTML과 자연스럽게 섞여있다는 것을 주의해야 한다. 사용자 정의 컴포넌트는 HTML과 거부감 없이 같은 레이아웃에 섞인다.
Metadata

메타데이터는 Angular가 클래스를 어떻게 다룰 것인지 알려준다.
HeroListComponent의 코드를 살펴보면 단지 클래스라는 것을 알 수 있다. "Angular"라고 되어 있는 것이 없어 프레임워크의 일부분이라는 것에 대한 증거는 없다.
사실 HeroListComponent는 Angular에게 컴포넌트라고 알려주지 않으면 실제로 단순한 클래스이다.
Angular에게 HeroListComponent가 컴포넌트라는 것을 알려주기 위해서 metadata를 클래스에 첨부해야 한다.
TypeScript에서 데코레이터를 사용해 메타데이터를 첨부할 수 있다. 다음은 HeroListComponent에 대한 메타데이터이다:
src/app/hero-list.component.ts (metadata)
@Component({
selector: 'hero-list',
templateUrl: './hero-list.component.html',
providers: [ HeroService ]
})
export class HeroListComponent implements OnInit {
/*...*/
}
@Component 데코레이터는 바로 아래의 클래스가 컴포넌트 클래스라는 것을 알려준다.
@Component 데코레이터는 Angular가 컴포넌트와 뷰를 나타내고 생성하는데 필요한 설정 객체를 필요로 한다.
아래는 가장 많이 사용하는 @Component 몇가지 설정 옵션들이다:
- selector: Angular에게 이 컴포넌트의 인스턴스를 생성해 HTML의 <hero-list> 태그가 있는 곳에 삽입하라고 알려주는 CSS 선택자이다. 예를들어, 앱의 HTML이 <hero-list></hero-list>를 포함하고 있다면 Angular는 HeroListComponent뷰의 인스턴스를 <hero-list></hero-list> 태그 사이에 삽입한다.
- templateUrl:이 컴포넌트의 HTML에 대한 모듈의 상대 주소다.
- providers: 컴포넌트가 필요로하는 서비스에 대한 의존성 주입 프로바이더에 대한 배열이다. 이것은 Angular에게 컴포넌트 생성자에게 보여줄 히어로의 리스트를 얻기 위해서 HeroService가 필요하다는 것을 알려주는 하나의 방법이다.

@Component 의 메타데이터는 Angular에게 어디서 컴포넌트로 명시한 주요 구성요소를 어디서 얻을 수 있는지 알려준다.
템플릿, 메타데이터, 컴포넌트가 함께 뷰를 나타낸다.
다른 메타데이터 데코레이터들 적용하는 것도 비슷한 방법으로 Angular에게 어떻게 동작할지 알려준다. @Injectable, @Input, @Output들도 자주 사용하는 데코레이터들이다.
구조적으로 가져가야할 것은 Angular에게 어떻게 해야할지를 알려주기 위해서 반드시 메타데이터를 코드에 추가해야 한다는 것이다.
Data binding
Directives
Services
Dependency injection
Wrap up
Angular 앱에 대한 8개의 기본 구성요소에 대한 기초에 대해서 알아봤다: