728x90
반응형

 Material Table Component

이번 포스트에서는 이전에 만들었던 list-box Component가 표현하는 부분을 Material Table을 이용해서 작성해 보겠습니다. 기본적인 테이블 구성과 함께 Pagination 까지 추가해서 간단하게 Paging까지 구현해보겠습니다.

사실 설명할 부분이 많지는 않습니다. DataSource만 Table에 잘 연결하면 알아서 보여주기 때문이죠. 그게 또 Component 기반 개발의 장점이기도 하구요.

먼저 CSS부터 수정하도록 하겠습니다. 다음은 list-box.component.css 파일입니다.

.example-container {
  display: flex;
  flex-direction: column;
  min-width: 300px;
  margin-top: 30px;
}

.mat-table {
  overflow: auto;
  max-height: 500px;
}

.mat-header-cell.mat-sort-header-sorted {
  color: black;
}

.list-table-style {
  font-family: Georgia;
}

.list-header-style {
  background-color: beige;
}

그 다음은 list-box.component.html 파일입니다.


<div class="example-container mat-elevation-z8">
  <mat-table class="list-table-style" #table [dataSource]="dataSource">

    <ng-container matColumnDef="bisbn">
      <mat-header-cell *matHeaderCellDef> ISBN </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.bisbn}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="btitle">
      <mat-header-cell *matHeaderCellDef> Title </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.btitle}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="bauthor">
      <mat-header-cell *matHeaderCellDef> Author </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.bauthor}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="bprice">
      <mat-header-cell *matHeaderCellDef> Price </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.bprice}} </mat-cell>
    </ng-container>

    <mat-header-row class="list-header-style" 
                    *matHeaderRowDef="displayedColumns">                  
    </mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
  </mat-table>

  <mat-paginator #paginator
                 [pageSize]="5"
                 [pageSizeOptions]="[5, 10, 20]"
                 showFirstLastButtons>
  </mat-paginator>
</div>

Table Component를 이용하기 때문에 book-search.module.ts에 관련된 Module을 import해 주어야 합니다.

import { MatTableModule } from '@angular/material/table';

그리고 Paging처리를 해야 하기 때문에 MatPaginatorModule 역시 import합니다.

import { MatPaginatorModule } from '@angular/material/paginator';

위의 HTML에서 가장 중요한 부분은 당연히 DataSource를 바인딩 하는 부분입니다.

<mat-table class="list-table-style" #table [dataSource]="dataSource">

Property binding을 이용하여 Component에 있는 dataSource라는 속성과 연결시켰습니다. 이 dataSource라는 속성은 도서정보에 대한 객체배열을 이용해서 만든 MatTableDataSource class의 객체입니다. JSON 데이터를 가져와서 만든객체입니다.

마지막으로 list-box.compoennt.ts파일의 내용입니다.

import { Component, OnInit } from '@angular/core';
import { HttpClient } from "@angular/common/http";
import { MatTableDataSource } from '@angular/material';
import { MatPaginator } from '@angular/material';
import { ViewChild } from '@angular/core';

interface IBook {
  bauthor: string;
  bdate: string;
  btranslator: string;
  bpublisher: string;
  btitle: string;
  bprice: number;
  bisbn: string;
  bimgurl: string;
}

@Component({
  selector: 'app-list-box',
  templateUrl: './list-box.component.html',
  styleUrls: ['./list-box.component.css']
})
export class ListBoxComponent {

  displayedColumns = ['bisbn', 'btitle', 'bauthor', 'bprice'];
  dataSource;
  books: IBook[];

  @ViewChild(MatPaginator) paginator: MatPaginator;

  constructor(private http: HttpClient) {
    this.http.get<IBook[]>('assets/data/book.json')
      .subscribe(res => {
        this.books = res;
        this.dataSource = new MatTableDataSource<IBook>(this.books);
        this.dataSource.paginator = this.paginator;
      });
  }
}

 Code Review

원래 Code Review란 표현은 Code Inspection에서 기인한 용어로 코드를 실제로 실행하지 않고 사람이 검토하는 과정을 통해 논리적인 잠재 오류를 찾아내고 이를 개선하는 작업을 지칭합니다.

그런데 여기서는 그냥 위의 코드를 살펴보자는 의미로 사용했습니다. ^^;;

코드를 좀 간단히 설명해보죠.

먼저 Table을 생성하는 구문은 다음과 같습니다.

<mat-table [dataSource]="dataArray">
  ...
</mat-table>

위의 코드에서 dataArray라고 되어있는 부분이 실제 Table에 rendering되는 데이터입니다. 배열형태로 되어 있고 배열안의 각각의 객체를 row로 가져와서 화면에 출력하게 됩니다.

다음은 Table의 컬럼을 표현하는 template입니다. 구문은 다음과 같습니다.


<ng-container matColumnDef="bisbn">
    <mat-header-cell *matHeaderCellDef> ISBN </mat-header-cell>
    <mat-cell *matCellDef="let element"> {{element.bisbn}} </mat-cell>
</ng-container>

matColumnDef 속성은 사용할 컬럼의 이름입니다. 이 부분은 list-box.component.ts파일안에 컬럼명에 대한 배열이 정의되는데 이 부분과 매칭되어야 합니다. 다음은 list-box.component.ts안에 정의된 컬럼명에 대한 배열입니다.

displayedColumns = ['bisbn', 'btitle', 'bauthor', 'bprice'];

그리고 아래의 구문에 의해 ISBN 컬럼의 제목과 내용이 출력됩니다. dataSource에 연결된 모든 row를 가져와서 element라는 변수에 반복적으로 할당 하면서 element.bisbn값을 테이블에 출력하라는 말입니다.


<mat-header-cell *matHeaderCellDef> ISBN </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.bisbn}} </mat-cell>

이와 같은 형태로 하나의 컬럼에 대한 데이터를 화면에 출력할 수 있습니다. 우리는 총 4개의 컬럼을 화면에 출력하고 있는 것이죠.

list-box.compoennt.ts에서는 사용할 데이터를 HttpClient의 get() method로 가져온 후 이를 다음의 코드를 이용해서 객체화 시켰습니다.

this.dataSource = new MatTableDataSource<IBook>(this.books);

dataSource와 연결시키기 위해 위에 있는 코드처럼 객체를 생성해서 연결하셔야 합니다.

Paginator의 사용은 코드에 나온것처럼 사용하시면 됩니다. 내부적으로 처리되기 때문에 사용하는 방법만 아시면 충분합니다.

TypeScript를 사용하기 때문에 interface를 이용하여 data type을 명확히 지정했습니다. 이 부분역시 이전 HTML Table Element로 작업했을 때와는 다르게 처리하셔야 합니다.


 정리

이제 1차적인 작업은 모두 끝났습니다. 논리적인 설명보다는 실제 사용할 화면을 만들면서 필요한 개념들에 대해서 그때 그때 설명하는 방식을 취했습니다. 이제 Component간의 상태공유에 대한 문제만 해결되면 우리의 프로그램은 얼추 완성할 수 있을 듯 보입니다.

조금만 더 진행시켜 일단 프로그램을 완성한 후 세부적인 내용들에 대해서 다시 짚어가며 살펴보도록 하겠습니다.

728x90
반응형

'Web Programming > Angular - TypeScript' 카테고리의 다른 글

Angular @Output 데이터공유  (0) 2018.08.28
Angular @Input 데이터공유  (0) 2018.08.28
Angular 예제 따라하기  (0) 2018.08.28
SPA형식의 Web Application  (0) 2018.08.28
Angular 개발환경세팅 하기  (0) 2018.08.28
728x90
반응형

 list-box Component View

이번 포스트에서는 도서 정보를 리스트 형태로 출력하는 list-box Component를 구현해 보도록 하겠습니다.

먼저 HTML Table Element를 이용하여 구현해보겠습니다. 사실 우리는 최종적으로 Angular Material Table Component를 이용할 것이기 때문에 HTML Table Element에 대한 CSS처리는 하지 않았습니다.

여하간 만들어지는 list의 형태는 다음 그림과 같습니다.

listbox-html-table-view

더 많은 책이 하단에 쭉 나열됩니다. 나중에는 book-search-main Component에서 만들어 놓은 Angular Material Select를 이용해 선택한 조건으로 책들에 대한 리스트가 출력되겠지만 지금은 그냥 조건없이 모든 책이 나열됩니다.

기존에 작성했던 book-search-main.component.html 파일을 열어서 HTML Select Element를 이용한 부분을 Material Select로 변경합니다.


<div class="bookSearch-outer">
  <div class="d-flex align-items-center p-3 my-3 text-white-50 bg-purple rounded box-shadow">
    <img class="mr-3" src="assets/images/search-icon.png" alt="" width="48" height="48">
    <div class="lh-100">
      <h5 class="mb-0 text-white lh-100">Search Result</h5>
    </div>
  </div>

  <div class="example-container">
    <mat-form-field>
      <mat-select placeholder="도서종류"  [(ngModel)]="selectedValue">
        <mat-option *ngFor="let category of bookCaterory"
                    [value]="category.value">
          {{ category.viewValue }}
        </mat-option>
      </mat-select>
    </mat-form-field>
  </div>
  
  <div>
    <app-search-box></app-search-box>
  </div>
  <div>
    <app-detail-box></app-detail-box>
  </div>
  <div>
    <app-list-box></app-list-box>
  </div>
</div>

일단 Angular Material의 MatSelectModule을 사용하기 때문에 book-search.module.ts에 다음과 같이 import작업부터 해야 코드에러가 나지 않을 듯 보입니다.

import { MatSelectModule } from '@angular/material/select';

mat-select가 Select box에 대한 Angular Material Component 입니다. 양방향 바인딩으로 selectedValue란 이름의 Component의 속성에 바인딩 시켜놓은 상태입니다.

mat-option은 Select box안의 각각의 Option Component입니다. 여러개가 존재할 수 있기 때문에 ngFor directive를 이용하여 반복처리 했습니다.

Angular는 구조적 지시자(Structural Directive)라는걸 제공합니다. DOM 요소를 추가하거나 삭제 혹은 반복처리를 함으로 화면의 구조를 변경할 때 사용합니다. 대표적으로는 ngIf와 ngFor가 있습니다. 이름에서 의미하다시피 ngIf는 boolean값을 입력받아 true일 경우 ngIf 가 선언된 Element를 DOM에 추가합니다. 만약 false일 경우에는 ngIf 가 선언된 Element는 DOM에서 제거됩니다. ngFor 는 반복가능한 데이터를 입력받아 DOM에 반복해서 Element를 표현할 때 사용합니다.

Directive에 대해서는 나중에 다른 포스트에서 다시 설명하겠습니다. 여기서는 구조적 지시자로 ngIf와 ngFor를 사용해서 DOM을 제어하는 방식에 대해서만 알아두시면 됩니다.

코드를 보고 유추하건대 bookCaterory는 배열형태의 데이터이고 배열의 각 원소는 객체이겠네요. 데이터 바인딩에서 학습했던 내용과 연계해서 생각해 보시면 됩니다.

그럼 아마도 book-search-main.component.ts에 다음과 같은 내용이 포함되어야 할 것입니다.

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-book-search-main',
  templateUrl: './book-search-main.component.html',
  styleUrls: ['./book-search-main.component.css',
  './offcanvas.css']
})
export class BookSearchMainComponent implements OnInit {

  selectedValue = null;
  bookCaterory = [
    {value: 'all', viewValue: '국내외도서'},
    {value: 'country', viewValue: '국내도서'},
    {value: 'foreign', viewValue: '국외도서'}
  ];
  
  constructor() { }

  ngOnInit() {
  }

}

그 다음은 실제 리스트가 출력되는 list-box.component.css 파일의 내용입니다. 위쪽 margin을 주기 위한 style을 정의해 놓았습니다.

.example-container {
  margin-top: 20px;
}

다음은 list-box.component.html 파일의 내용입니다.


<table class="example-container">
  <thead>
  <th>ISBN</th>
  <th>Title</th>
  <th>Author</th>
  <th>Price</th>
  </thead>
  <tbody>
    <tr *ngFor="let book of books">
      <td>{{book.bisbn}}</td>
      <td>{{book.btitle}}</td>
      <td>{{book.bauthor}}</td>
      <td>{{book.bprice}}</td>
    </tr>
  </tbody>
</table>

코드를 수행시키기 위해 먼저 book.json 파일을 하나 준비합니다. book.json 파일의 내용은 다음과 같이 작성하시면 됩니다.

단, btranslator는 번역자를 의미합니다. 이 값이 존재하면 외국서적이라는 말이겠죠. 만약 국내도서면 이 값이 ""로 표현됩니다. 다른 key값들에 대해서는 이름에서 그 의미를 충분히 유추할 수 있을 듯 합니다.

[  
   {  
      "bauthor": "카일 루든(Kyle Loudon)",
      "bdate":"2000년 04월",
      "btranslator":"허 욱",
      "bpublisher":"한빛미디어(주)",
      "btitle":"C로 구현한 알고리즘",
      "bprice":25000,
      "bisbn":"89-7914-063-0",
      "bimgurl":"http://image.hanbit.co.kr/cover/_m_1063m.gif"
   },
   {  
      "bauthor":"권기경, 박용우",
      "bdate":"2002년 09월",
      "btranslator":"",
      "bpublisher":"한빛미디어(주)",
      "btitle":"IT EXPERT, 모바일 자바 프로그래밍",
      "bprice":23000,
      "bisbn":"89-7914-206-4",
      "bimgurl":"http://image.hanbit.co.kr/cover/_m_1206m.gif"
   },
   ...
   ...
   ...
]   

작성한 데이터 파일을 src/assets/data 폴더 아래에 저장합니다. 이 JSON data를 불러오기 위해 HttpClientModule를 이용합니다. 더 쉽게 파일로 import해서 쓸 수 있지만 여기서는 HttpClientModule로 처리했습니다.

book-search.module.ts 파일안에 HttpClientModule에 대한 import 구문을 작성합니다.

import { HttpClientModule } from "@angular/common/http";

아래는 list-box.component.ts 파일의 내용입니다.

import { Component, OnInit } from '@angular/core';
import { HttpClient } from "@angular/common/http";

interface IBook {
  bauthor: string;
  bdate: string;
  btranslator: string;
  bpublisher: string;
  btitle: string;
  bprice: number;
  bisbn: string;
  bimgurl: string;
}

@Component({
  selector: 'app-list-box',
  templateUrl: './list-box.component.html',
  styleUrls: ['./list-box.component.css']
})
export class ListBoxComponent implements OnInit {

  books: IBook[];

  constructor(private http: HttpClient) {
    this.http.get<IBook[]>('assets/data/book.json')
      .subscribe(res => this.books = res);
  }

  ngOnInit() {
  }

}

약간 이상한 코드가 들어있는데 그 이유는 책의 정보를 가져오기 위해 HttpClient의 get() method를 호출하면서 Arrow Function을 이용해 코드를 작성했기 때문입니다. 이 부분은 나중에 RxJS를 설명할 때 더 자세히 봐야 할 듯 하고 지금은 book.json에 대한 HTTP연결로 JSON 데이터를 가져온다고 이해하시면 충분합니다.


 문제점

도서정보에 대한 JSON을 작성해서 실행해보시면 아시겠지만 출력은 잘 됩니다.

하지만 몇가지 문제가 있습니다.

  • 책이 100권이 있으면 밑으로 쭉 나열되게 됩니다. Paging 처리를 해야 하는데 이것또한 쉬운작업은 아닙니다.

  • Event 처리하기가 쉽지 않습니다. 각 행을 클릭하면 해당 책의 세부정보를 detail-box Component를 이용하여 View에 출력해야 합니다. 클릭이벤트를 처리하기가 쉽지 않네요.

  • book-search-main.component.html에서 만들어놓은 Select Box의 선택 정보를 알아와서 그에 맞추어 책들을 필터링 해야 하는데 어떤 도서를 선택했는지 현재로서는 알 방법이 없습니다.

이 외에도 Table Header를 클릭해서 리스트를 Sorting하는 것과 같은 일반적인 테이블이 가지는 기능을 우리가 추가로 구현해야되는 문제가 있습니다. 제대로 사용할려면 부가적인 작업이 훨씬 더 많이 들어가야 합니다.

이와 같은 문제를 Material의 Table Component를 이용하면 쉽게 해결할 수 있습니다. 다음 포스트에서는 도서 리스트를 출력하는 부분을 Material Table Component를 이용하여 다시 작성해 보겠습니다.

728x90
반응형

'Web Programming > Angular - TypeScript' 카테고리의 다른 글

Angular @Input 데이터공유  (0) 2018.08.28
Angular Material Table  (0) 2018.08.28
SPA형식의 Web Application  (0) 2018.08.28
Angular 개발환경세팅 하기  (0) 2018.08.28
Angular 소개  (0) 2018.08.28
728x90
반응형

먼저 실습의 결과화면을 한번 보고 개념적으로 무엇을 할 것인지 파악한 후 코드를 살펴보면 될 듯 싶습니다. 여기를 누르면 실습의 결과 Web Application을 볼 수 있습니다. 상단에 Navigation Bar가 있고 각 메뉴를 클릭하면 내용이 그에 맞게 변하는 SPA형식의 Web Application입니다.

UI 부분은 Bootstrap을 살짝 이용했습니다. CSS를 안쓰니 워낙 안예뻐서요. 약간 개념적으로 이상한 얘기도 좀 나오는데 천천히 이해하시면 됩니다. 일단 만든 Application이 어떤 형태인지는 이해하는것은 그리 어렵지 않아보입니다.

그럼 한번 시작해보죠.


 SPA( Single Page Application )

요즘 만들어지는 거의 대부분의 Front End Web Application은 SPA 형태입니다. Web Application이 하나의 Web Page로 구성되는 것이죠. 이와 대비되는 개념이 기존에 우리가 많이 했었던 JSP, ASP, PHP같은 것들입니다. 이 기술들은 모두 SSR(Server Side Rendering)기반의 Round Trip 방식의 Web Application을 개발하는데 사용됩니다.

기존의 Web Application은 Client가 새로운 Web Page를 요청할 때 마다 서버쪽에서 Web Page를 동적으로 만들어서 Client Browser에게 전송하는 방식을 취했습니다. 이 방식의 장,단점을 잠깐 살펴봐야 합니다. 장점은 서버쪽에서 모든 작업이 이루어지기 때문에 개발하기가 용이하다는 점입니다. 이미 개발방식도 정형화되어 있고 jQuery 정도만 익혀서 결과 Web Page에 적용하는 식으로 Client쪽 처리도 쉽게 할 수 있습니다.

기존 Desktop 환경에서는 이 방식이 크게 문제가 되지 않았습니다. 하지만 Web Application의 사용환경이 Desktop환경에서 Mobile환경으로 넘어가면서 다음과 같은 문제가 발생하기 시작합니다.

  • 클라이언트가 새로운 페이지를 요청하고 받을 때 마다 web browser 화면 전체가 결과 Page로 Refresh됩니다. 필요한 데이터만 받아서 필요한 부분만 갱신하면 되지 전체 페이지를 다 받아서 새로 고침하는 것은 네트워크 사용량을 생각해봐도 비효율적입니다.

  • Mobile환경에서 Client는 이미 Native App을 사용하는 방식으로 UX가 확고하게 굳어져 있습니다. 따라서 우리의 Web Application도 마치 Native App처럼 동작하도록 만들어 제공해야 한다는 것이죠.

결국 위와 같은 문제를 해결하기 위해 나온 모던 웹 패러다임이 바로 SPA입니다. Network traffic의 감소 및 사용성 관점에서 상당히 가치있는 Front End 개발방식이라고 볼 수 있습니다. 하지만 SPA도 단점이 없는 것은 아닙니다. 일반적으로 두가지의 단점을 많이 이야기 합니다.

  • 초기 로딩 속도 문제
  • 검색엔진최적화(SEO, Search Engine Optimization) 문제

실습인데 설명이 너무 길어지는군요. 이 문제는 여기서 따로 언급하지는 않겠습니다. 여하간 SEO 문제를 해결하기 위해 Angular Router를 이용하여 PathLocationStrategy라는 Location 정책을 이용해 우리의 Angular Application을 작성하겠습니다.


 Module 생성

우리는 이미 AppModule이라고 불리는 Root Module을 가지고 있습니다. 여기에 추가적으로 다른 Module을 만들어서 개발할 수 있습니다. 먼저 Module에 대해 간단히 알아보고 우리 프로그램에 맞게 Module을 구성해 보도록 하겠습니다.

Angular의 Module은

연관성이 있는 Angular의 구성요소들을 하나의 단위로 묶은 것

을 지칭합니다. 또한 Angular Application은 크게 본다면 이런 Module의 집합이라고 할 수 있습니다. JavaScript에서 말하는 Module과는 다른 개념입니다.

아주 간단한 application인 경우 Root Module 하나로 구성할 수 있지만 일반적으로 여러개의 Module을 이용해서 구성하게 됩니다. 일반적으로 다음과 같은 형태의 Module을 이용합니다.

  • Feature Module

    특정 화면을 구성하는 구성요소를 묶어서 Module로 관리할 수 있습니다. 우리예제에서 Home은 단일 View로 구성되어 있습니다. 따로 Module을 만들어서 Home에 대한 구성요소를 관리해도 됩니다. 하지만 우리 예제에서는 Home에 대한 Component를 Root Module에서 관리하도록 하겠습니다. 

    하지만 도서 검색이나 영화 검색같은 경우 여러 요소들이 필요할 테고 각각을 Module로 따로 관리하는게 좋습니다. Application안에 여러 화면이 존재할 경우 각 화면별로 Module화를 시키지 않으면 추후에 구성요소의 관리가 어려워짐은 당연합니다.

    또 Application 전역에서 사용하는 구성요소들을 따로 묶어서 Module로 만들 수도 있습니다. 이런 기능들은 Root Module에 import가 될 필요가 있는 것들로 간단한 예를 들자면 Authentification Module이나 Routing Module등이 있습니다.


  • Shared Module

    Feature Module에 의해서 공통적으로 사용되는 구성요소들을 묶어서 Module로 관리할 수 있습니다. 주로 Feature Module에서 공통적으로 사용되는 Directive나 Pipe같은 것들이 포함됩니다.

먼저 Routing Module을 생성하고 그 안에서 Router를 구성하고 등록해보겠습니다.
그 후 Routing Module을 Root Module에서 가져다 사용하는 식으로 작성을 해 보죠.

command 창을 열고 다음의 명령을 이용하여 새로운 Module을 하나 생성합니다.

ng generate module app-routing

정상적으로 실행되면 src/app/app-routing 폴더가 생성되고 그 안에 app-routing.module.ts 파일이 생성됩니다.

조금뒤에 이 Module안에 Router를 작성하게 되겠죠. 우리가 가지고 있는 app.module.ts라는 Root Module에 Router를 생성, 등록 해도 됩니다. 하지만 실제 Application을 작성할 때는 사용되는 Routing이 많아지게 되는데 이때는 Routing Module로 빼서 관리하시는게 좋습니다.


 각 Routing이 사용할 Component 생성

각 Routing 경로가 사용할 Component를 생성합니다. 그런데 위에서 특정 화면을 구성하는 구성요소를 Module화 시켜서 사용하는게 좋다고 했으니 우리의 2가지 화면에 대해 Module을 생성하고 이 안에 Component를 생성하도록 하겠습니다.

Home은 아까 언급했듯이 별다른 기능이 없는 View이기 때문에 따로 Module로 생성하지 않고 도서 검색에 대한 Module과 영화 검색에 대한 Module만 만들도록 하겠습니다.

Home 화면을 담당할 Component는 src/app/pages 하단에 생성하고 Root Module에서 직접 import해서 사용하도록 생성합니다.

command 창에서 Angular CLI를 이용해 Component를 생성합니다.

ng generate component pages/home

이제 도서 검색을 위한 Module을 생성하고 그 안에 Component를 생성합니다.

ng generate module bookSearch 
ng generate component bookSearch/bookSearchMain

마지막으로 영화 검색을 위한 Module을 생성하고 그 안에 Component를 생성합니다.

ng generate module movieSearch 
ng generate component movieSearch/movieSearchMain

정상적으로 수행되면 아래의 그럼처럼 각각의 폴더안에 파일들이 생성되게 됩니다.

step1-scaffolding-folder


 Routing Module 수정

이제 Routing Module을 수정하여 Router를 구성합니다. app-routing.module.ts를 다음과 같이 수정합니다.

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

// Angular Router Module import
import { Routes, RouterModule } from "@angular/router";

// Routing 처리를 할 각각의 Component import
import { HomeComponent } from "../pages/home/home.component";
import { BookSearchMainComponent } from
    "../book-search/book-search-main/book-search-main.component";
import { MovieSearchMainComponent } from
    "../movie-search/movie-search-main/movie-search-main.component";

// Router 생성( path 표시할 때 Root path에 대한 '/'는 제외 )
const routers: Routes = [
  { path : '', component : HomeComponent },
  { path : 'book', component : BookSearchMainComponent },
  { path : 'movie', component : MovieSearchMainComponent }
];

@NgModule({
  imports: [
    CommonModule,
    RouterModule.forRoot(routers)
  ],
  declarations: [],
  exports: [RouterModule]
})
export class AppRoutingModule { }

 Root Module 수정

Routing Module이 만들어졌으니 이제 Root Module에서 Routing Module을 불러들이는 코드를 작성해야 합니다.

app.module.ts 파일의 내용입니다.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

// BrowserAnimationsModule import 구문 추가
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

// MatTableModule import 구문 추가
import { MatTableModule } from '@angular/material/table';

import { AppComponent } from './app.component';
import { HomeComponent } from './pages/home/home.component';

// Feature Module import
import { BookSearchModule } from "./book-search/book-search.module";
import { MovieSearchModule } from "./movie-search/movie-search.module";

// Routing Module import
import { AppRoutingModule } from "./app-routing/app-routing.module";

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    MatTableModule,
    AppRoutingModule,
    BookSearchModule,
    MovieSearchModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

 Navigation Menu 작성

이제 Navigation Menu를 만들어야 합니다. Routing Module을 이용해 Router의 구성과 등록이 완성되었으나 해당 Routing Path에 대한 View를 어디에 표시할지는 아직 지정하지 않았습니다. app.component.html을 수정해 RouterOutlet directive를 이용해 View의 rendering위치를 지정해야 합니다.

여기서는 Bootstrap을 이용해서 화면을 구성했습니다. Bootstrap의 예제중에 Blog 예제가 있는데 그 형식을 가져다가 사용했습니다. Bootstrap을 사용하기 위해서는 다음과 같이 Bootstrap을 설치하여야 합니다.

npm install bootstrap@4.0.0-beta.2

버전에 약간 주의하셔야 합니다. 현재 최신 버전(bootstrap@4.0.0-beta.3)의 Bootstrap은 Angular CLI로 Production build를 했을 때 bundling 오류가 발생합니다.

설치가 완료되면 Bootstrap을 import하셔야 합니다. .angular-cli.json 파일을 다음과 같이 수정합니다.

   "styles": [
        "../node_modules/bootstrap/dist/css/bootstrap.min.css",
        "styles.css"
   ],

이제 app.component.html 파일을 수정합니다.

<nav>
    <a routerLink="/">Home</a>
    <a routerLink="/book">도서검색</a>
    <a routerLink="/movie">영화검색</a>
</nav>
<router-outlet></router-outlet>

쉽게 보기 위해 Bootstrap은 걷어내고 실제 필요한 부분만 명시했습니다. 주의해서 보셔야 할 건 routerLink 입니다. <a>의 href 속성을 이용하면 서버에 request를 보내게되니 href를 이용하지 않습니다. 각각의 메뉴를 클릭했을 때 해당 URL을 Router에 전달하고 Router에 의해서 Component가 선택되서 <router-outlet></router-outlet>안에 Component가 지정한 HTML이 출력되게 됩니다.

결과가 잘 나오나요? Home 화면의 내용을 바꾸실려면 src/app/pages/home 폴더 안에 home.component.html을 적절히 수정하시면 됩니다.

참고로 다음과 같은 routerLinkActive directive를 이용하면 routerLink directive의 값과 현재 browser URL이 정확히 일치할 때 특정 style의 class를 지정할 수 있습니다.

<nav>
    <a routerLink="/">Home</a>
    <a routerLink="/book"
       [routerLinkActiveOptions]="{ exact: true }"
       routerLinkActive="menuActiveClass">>도서검색</a>
    <a routerLink="/movie">영화검색</a>
</nav>
<router-outlet></router-outlet>

위의 예처럼 링크를 클릭해서 특정 경로로 Routing을 할 수도 있지만 버튼을 클릭했을 때 처럼 프로그램적으로 Routing을 변경해야 하는 경우도 있을 수 있습니다. 이런경우는 Angular Router의 navigate method를 이용하시면 됩니다.

import { Router } from '@angular/router';
...
...
constructor(private route:Router) { }
...
...
gotoBook() {
    // Router객체에 대해 method호출
    this.route.navigate(['book']);
}

현재까지 우리가 작성한 Angular Project에 대해 production build를 진행하실려면 다음과 같이 하시면 됩니다.

ng build --prod --base-href=/my-base-url/


 도서 검색 화면

3개의 메뉴 중 Home 메뉴는 단일 페이지 이기 때문에 적절하게 수정해서 화면에 보여주면 됩니다. 먼저 최종적으로 만들어진 도서 검색 화면을 한번 보고 View을 어떻게 구성할지 개념적으로 확인하면 될 듯 싶습니다. 아래의 그림이 최종 만들어진 도서검색 화면입니다.

exercise-result

총 4개의 View로 구성되어 있습니다. 파란색으로 되어 있는 가장 큰 View안에 검색결과를 보여주는 영역과 도서 종류를 선택하는 Select Box가 들어 있습니다. 부모 View안에 빨간색으로 되어있는 3개의 자식 View가 포함되어 있네요. 맨 위의 View는 검색어를 입력할 수 있는 View이고 제일 아래의 View는 검색어에 해당하는 책에 대한 리스트를 표현하는 View입니다. 가운데 View는 리스트에서 특정 책을 선택하면 그 책의 내용을 자세하게 출력해주는 View입니다.

일단 화면을 만드는데 집중하고 실제 프로그램이 동작하는 로직에 관련된 부분은 나중에 service를 설명하면서 추가하도록 하겠습니다.


 AppComponent 수정

이전에 만들어 놓은 mySearchProject를 수정하여 도서검색 화면을 만들고 그에 따른 Component들을 생성, 등록까지 진행하도록 하겠습니다.

src/app 폴더안에 app.component.ts 파일을 열면 다음과 같은 내용을 보실 수 있습니다.

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css', './blog.css']
})
export class AppComponent {
  title = 'app';
}

이 Component가 우리의 Root Component입니다.

selector: 'app-root' 설정에 의해 이 Component는 template 코드내에서 <app-root></app-root>로 되어 있는 부분을 rendering 한다는 것을 알 수 있습니다.
또한 templateUrl에 의해 app.component.html을 이용해 rendering한다는 것도 파악할 수 있겠네요.

index.html을 보시면 다음과 같이 <app-root></app-root>로 되어있는 부분이 보이고 이 부분이 우리 Component에 의해서 rendering되게 됩니다.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>MySearchProject</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <!-- Material Icon 설정. -->
  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
  <app-root></app-root>
</body>
</html>

결국 index.html안의 <app-root></app-root> 부분은 app.component.html의 내용으로 rendering된다는 것을 파악할 수 있습니다.

이제 app.component.html의 코드를 보죠. 위에서 Routing Module을 이용했기 때문에 다음과 같은 코드가 나옵니다. Bootstrap 코드도 포함시켰습니다.

<div class="container">
  <header class="blog-header py-3">
    <div class="row flex-nowrap justify-content-between align-items-center">
      <div class="col-4 pt-1">

      </div>
      <div class="col-4 text-center">
        <a class="blog-header-logo text-dark" href="#">my Search Project</a>
      </div>
      <div class="col-4 d-flex justify-content-end align-items-center">

      </div>
    </div>
  </header>

  <div class="nav-scroller py-1 mb-2">
    <nav class="nav d-flex justify-content-between">
      <a class="p-2 text-muted" routerLink="/">Home</a>
      <a class="p-2 text-muted" routerLink="/book">도서 검색</a>
      <a class="p-2 text-muted" routerLink="/movie">영화 검색</a>
      <a class="p-2 text-muted" href="#"></a>
      <a class="p-2 text-muted" href="#"></a>
      <a class="p-2 text-muted" href="#"></a>
      <a class="p-2 text-muted" href="#"></a>
      <a class="p-2 text-muted" href="#"></a>
      <a class="p-2 text-muted" href="#"></a>
      <a class="p-2 text-muted" href="#"></a>
      <a class="p-2 text-muted" href="#"></a>
      <a class="p-2 text-muted" href="#"></a>
    </nav>
  </div>

  <div class="jumbotron p-3 p-md-5 text-dark rounded bg-warning">
    <div class="col-md-12 px-0">
      <router-outlet></router-outlet>
    </div>
  </div>

</div>

Bootstrap을 이용했기 때문에 Style에 관련된 코드가 많네요. 여하간 Navigation Menu를 작성하고 각 Menu를 클릭하면 Router에게 routerLink에 명시된 경로를 전달하게 됩니다. 그러면 Router는 해당 경로에 매핑되는 Component를 찾게되고 해당 Component는 <router-outlet></router-outlet>위치에 View를 Rendering 하게 됩니다.

결과적으로 도서 검색 메뉴를 클릭하면 <router-outlet></router-outlet> 부분에 book-search-main.component.html의 내용이 rendering되게 되고 이제 그 내용을 수정해서 화면을 다시 구성합니다. View를 추가하기 위해 Component를 생성하는 작업을 진행해야 합니다.


 Component 추가

book-search-main.component.html은 내부에 3개의 View 영역을 포함하고 있습니다.

  • 첫번째 영역 : 검색 키워드를 입력하고 검색 버튼을 눌러 실행시키는 View 영역.
  • 두번째 영역 : 검색된 책을 선택하면 책의 세부정보가 출력되는 View 영역.
  • 세번째 영역 : 검색된 책들의 리스트를 출력하기 위한 View 영역.

이렇게 3개의 View를 이용해서 화면을 구성할 것이고 3개의 Component를 추가하여 화면을 구성하려 합니다.

Angular CLI를 이용하여 다음과 같이 실행해서 새로운 Component를 추가합니다.

ng generate component bookSearch/search-box

Angular CLI의 generate를 이용하여 Component 생성 시 Component를 구성하는 관련 파일들을 자동으로 손쉽게 생성할 수 있습니다. generate를 다 쓰지 않고 앞글자인 g 만 써도 됩니다. generate는 뒤에 어떤 요소를 생성할 것인지 그리고 요소명은 무엇인지를 받아 특정 요소를 생성하게 됩니다. 즉, Component만 생성할 수 있는건 아닙니다.

생성된 src/app/book-search/search-box 폴더 안에 있는 search-box.component.ts 파일을 열어서 selector를 확인해보니 app-search-box로 지정되어 있습니다. 우리가 template 코드에서 <app-search-box></app-search-box>을 이용하면 이 Component가 해당 영역을 rendering하게 되겠네요.

이와 유사하게 2개의 Component를 더 생성합니다. 다음과 같이 실행해서 새로운 Component를 추가합니다.

ng generate component bookSearch/detail-box

ng generate component bookSearch/list-box

자 이제 생성된 각각의 Component에 대한 selector를 참조해 src/app/book-search/book-search-main 안의 book-search-main.component.html의 내용을 다음과 같이 수정합니다.

<div class="bookSearch-outer">
  <div class="d-flex align-items-center p-3 my-3 text-white-50 bg-purple rounded box-shadow">
    <img class="mr-3" src="assets/images/search-icon.png" alt="" width="48" height="48">
    <div class="lh-100">
      <h5 class="mb-0 text-white lh-100">Search Result</h5>
    </div>
  </div>

  <div class="form-group col-md-4">
    <label for="inputState">도서 종류</label>
    <select id="inputState" class="form-control">
      <option selected>선택하세요...</option>
      <option>국내외도서</option>
      <option>국내도서</option>
      <option>국외도서</option>
    </select>
  </div>

  <div>
    <app-search-box></app-search-box>
  </div>
  <div>
    <app-detail-box></app-detail-box>
  </div>
  <div>
    <app-list-box></app-list-box>
  </div>
</div>

또한 src/app/book-search/book-search-main 안의 book-search-main.component.css의 내용을 다음과 같이 작성합니다. CSS에 대한 설명은 생략합니다.

.bookSearch-outer {
  font-family: Georgia !important;
  width: 70%;
  text-align: center;
  margin: 0 auto;
}

 각 Component의 View 작성

이제 각각의 Component의 templateUrl에 명시된 html을 Angular Material을 이용해 우리가 사용할 화면을 만들어 냅니다.

제일 먼저 상단의 search-box 영역에 대한 HTML을 작성합니다.

다음과 같이 src/app/book-search/search-box 폴더안의 search-box.component.html의 내용을 수정합니다.

<div class="example-container">
  <mat-toolbar class="search-toolbar-style">Search Keyword : </mat-toolbar>
  <mat-form-field>
    <input matInput placeholder="Search Keyword">
  </mat-form-field>
  <button mat-raised-button color="warn">Search!</button>
</div>

search-box.component.css의 내용은 다음과 같이 수정합니다.

.search-toolbar-style {
  font-family: Georgia;
  color: white;
  background-color: teal;
  margin-bottom: 20px;
}

Angular Material을 이용했기 때문에 해당 Element에 대한 Material Module을 book-search.module.ts안에 import해 줍니다.

다음은 book-search.module.ts 파일의 내용입니다.

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { BookSearchMainComponent } from './book-search-main/book-search-main.component';
import { SearchBoxComponent } from './search-box/search-box.component';
import { ListBoxComponent } from './list-box/list-box.component';
import { DetailBoxComponent } from './detail-box/detail-box.component';

import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material';
import { MatButtonModule } from '@angular/material/button';
import { MatToolbarModule } from '@angular/material/toolbar';

@NgModule({
  imports: [
    CommonModule,
    MatFormFieldModule,
    MatInputModule,
    MatButtonModule,
    MatToolbarModule
  ],
  declarations: [BookSearchMainComponent, 
                 SearchBoxComponent, 
                 ListBoxComponent, 
                 DetailBoxComponent]
})
export class BookSearchModule { }

일단 여기까지 작성하고 실행을 시켜보면 다음과 같은 화면을 볼 수 있습니다.

search-box-view

화면이 잘 나오나요? 아직 데이터 바인딩과 이벤트에 대한 내용은 설명하지 않았기 때문에 키워드를 입력하거나 버튼을 눌러도 아무런 반응을 하지 않습니다.

이와 비슷하게 가운데 detail-box의 View는 다음과 같이 작성하시면 됩니다. list-box는 데이터 바인딩에 대한 내용을 배워야지 사용할 수 있으니 list-box의 View는 데이터 바인딩에 대해 설명하고 작성하겠습니다.

아래는 detail-box Component에 대한 각각의 코드입니다.

detail-box.component.css 파일입니다. src/assets/images 폴더안에 book-icon.jpg파일을 하나 넣어두셔야 합니다.

.example-card {
  width: 500px;
  margin: 0 auto;
}

.example-header-image {
  background-image: url('/assets/images/book-icon.jpg');
  background-size: cover;
}

.book-image {
  width: 100px !important;
}

.detail-header-style {
  font-family: Georgia;
}

detail-box.component.html 파일입니다.

<mat-card class="example-card">
  <mat-card-header class="detail-header-style">
    <div mat-card-avatar class="example-header-image"></div>
    <mat-card-title>제목 : Angular 일주일 완성</mat-card-title>
    <mat-card-subtitle>저자 : 홍길동</mat-card-subtitle>
  </mat-card-header>
  <img mat-card-image class="book-image" src="">
  <mat-card-content>
    <p>
      ISBN : 123-456, 도서 가격 : 5000, 출판일 : 2017년 12월
    </p>
  </mat-card-content>
  <mat-card-actions>
    <button mat-button mat-raised-button color="primary">바로 구입</button>
  </mat-card-actions>
</mat-card>

Material Card Layout Component를 사용했기 때문에 해당 Module에 대한 처리를 book-search.module.ts에 해주어야 하겠죠?

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { BookSearchMainComponent } from './book-search-main/book-search-main.component';
import { SearchBoxComponent } from './search-box/search-box.component';
import { ListBoxComponent } from './list-box/list-box.component';
import { DetailBoxComponent } from './detail-box/detail-box.component';

import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material';
import { MatButtonModule } from '@angular/material/button';
import { MatToolbarModule } from '@angular/material/toolbar';

import { MatCardModule } from '@angular/material/card';

@NgModule({
  imports: [
    CommonModule,
    MatFormFieldModule,
    MatInputModule,
    MatButtonModule,
    MatToolbarModule,
    MatCardModule
  ],
  declarations: [BookSearchMainComponent, 
                 SearchBoxComponent, 
                 ListBoxComponent, 
                 DetailBoxComponent]
})
export class BookSearchModule { }

 결과 화면

지금까지 작성한 내용을 실행시켜보면 다음과 같은 화면을 보실 수 있습니다.

step-1-result


이번 포스트에서는 Component를 추가하고 Angular Material을 이용해 View를 작성해보았습니다. 다음 포스트에서는 데이터 바인딩에 대한 내용을 알아보도록 하겠습니다.

728x90
반응형

'Web Programming > Angular - TypeScript' 카테고리의 다른 글

Angular @Input 데이터공유  (0) 2018.08.28
Angular Material Table  (0) 2018.08.28
Angular 예제 따라하기  (0) 2018.08.28
Angular 개발환경세팅 하기  (0) 2018.08.28
Angular 소개  (0) 2018.08.28
728x90
반응형

 Angular 개발환경 - Node.js, WebStorm, TypeScript

이번 포스트에서는 Angualr의 개발환경을 세팅하고 Angular CLI를 이용하여 기본적인 Hello World App을 생성, 실행하는 것까지 진행하도록 하겠습니다.

제일 먼저 해야 할 일은 Node.js를 설치하는 것입니다. Angular CLI와 TypeScript가 node module로 존재하기 때문에 npm을 이용하여 이 두가지를 설치해야 합니다.

먼저 Node.js사이트에 접속해 LTS 버전이나 최신버전 둘 중 하나를 선택해 다운로드 합니다. (어떤것을 설치해도 상관없습니다.)nodejs download

저는 LTS 버전으로 다운로드 했습니다. 다운로드가 끝나면 기본 형태로 설치를 진행합니다. 설치가 끝나면 C:/Program Files/nodejs 폴더가 만들어지게 됩니다.

이제 command 창을 열어서 다음과 같은 명령어를 실행합니다.

npm

nodejs_npm

npm(Node Package Manager)이 정상적으로 동작하면 이제 npm을 이용해 typescript를 설치할 수 있습니다. 설치는 local mode와 global mode로 설치가 가능합니다. 여기서는 편의상 global mode로 설치합니다. global mode로 모듈을 설치하면 모든 프로젝트에서 사용가능한 형태로 시스템에 설치됩니다. local mode로 설치하면 해당 프로젝트에서만 사용가능한 형태로 모듈이 설치 되게 됩니다. (일반적으로는 local mode를 선호합니다.)

command 창에서 다음의 명령어를 실행해 typescript를 global mode로 설치합니다.

npm install -g typescript

nodejs_npm_typescript

typescript 2.6.2가 설치되었습니다.

global mode로 설치하면 windows 시스템을 기준으로 $USER_HOME/AppData/Roaming/npm/node_modules에 설치됩니다.

이제 사용할 IDE(Integrated Development Environment)를 설치합니다. 여기서는 WebStorm(유료)을 이용합니다. Visual Studio Code(무료)를 사용하셔도 됩니다. WebStorm은 유료이지만 30일 trial을 사용할 수 있고 Student 라이선스를 이용하면 1년간 무료로 사용할 수 도 있습니다. 개인적으로는 비용이 좀 들지만 WebStorm을 추천합니다. Front End 개발은 역시 WebStorm이 편합니다. ( 사실 손에 익어서 그렇습니다. Visual Studio Code를 이용해도 아무 문제 없습니다. )

JetBrains 사이트로 접속한 후 WebStorm을 다운로드 받습니다.

다운로드가 완료되면 기본형태로 설치합니다. 설치가 끝나면 프로젝트를 생성할 수 있는 화면이 나오게 되는데 일단 이 화면에서 대기합니다.

프로젝트는 Angular CLI를 이용해서 생성합니다.


 Angular 개발환경 - Angular CLI

일반적으로 Framework를 도입할 때 가장 힘든점 중 하나는 개발환경 구축입니다. 기본적인 폴더구조를 숙지해서 만들어야 하고 기본적으로 사용되는 설정 파일들도 다수 존재합니다. 처음에는 대부분 뭐가먼지 알기 힘들죠. 코드를 작성한 후 Build 설정, Bundler 설정, 테스팅과 배포등 너무 많은 일을 해야하고 설정방법 또한 복잡합니다.

Angular 역시 마찬가지입니다. Mike Brocchi( Angular CLI contributor )의 Twitter 설문을 예로 들어보죠. 설문에서 나온것처럼 초기 환경 세팅과 복잡성을 가장 큰 문제 중 하나로 여기고 있는걸 볼 수 있습니다.

what is angular barrier

다행스럽게 Angular는 Angular CLI를 제공함으로 이런 복잡함을 해결하고 있습니다. Angular CLI를 이용할 경우와 그렇지 않는 경우를 간단히 그림으로 표현하면 다음과 같습니다.

with angular CLI

Angular Project를 쉽게 생성하고 프로젝트를 시작하기 위한 scaffolding을 포함해서 다양한 기능을 제공하는 것이 바로 Angular CLI입니다. 사실 쓰지 않을 이유가 없습니다.

그럼 Angular CLI를 설치해보도록 하죠. command 창을 열어서 다음과 같이 실행합니다.

npm install -g @angular/cli

npm을 이용하여 Angular CLI를 global mode로 설치합니다. 설치하는데 시간이 좀 걸립니다. 설치가 끝나면 다음과 같이 실행해서 Angular CLI의 버전을 확인해 보세요.

ng --version

Angular CLI version


 Angular 프로젝트 생성

Angular CLI의 설치가 끝났으니 이제 Angular CLI를 이용하여 프로젝트를 하나 생성합니다. 프로젝트명은 mySearchProject로 하겠습니니다.

프로젝트 폴더는 C:/mySearchProject로 생성할 것이기 때문에 저는 현재 command 창의 working directory를 C:/로 잡아놓고 다음과 같이 입력합니다.

ng new mySearchProject

시간이 제법 오래 걸립니다. 필요한 의존 모듈들을 npm을 이용해 다운로드 받기 때문입니다. 프로젝트 생성이 끝나면 자동으로 생성된 설정 파일과 기본 Skeleton 코드가 프로젝트 폴더안에 위치하게 됩니다. 만약 의존 모듈을 설치하지 않고 프로젝트 기본 구조와 파일만 scaffolding할 목적이라면 --skip-install option을 이용하시면 됩니다.

Angular CLI는 나름대로의 Coding Convention을 가지고 있습니다. 그 규칙에 대해서는 나중에 다른 포스트에서 알아보겠습니다.

이렇게 Angular CLI를 이용해서 프로젝트를 생성할 수 있는데 이 프로젝트 구조와 Coding Convention이 Angular의 표준형태라고 보시면 됩니다.

설정파일에 대한 내용은 나중에 다시 보기로 하고 일단 WebStorm으로 해당 프로젝트 폴더를 open합니다. 아래의 그림처럼 WebStorm에서 프로젝트 폴더가 보이게 됩니다.

WebStorm Angular project

기본적으로 Git Repository가 같이 생성됩니다. 꼭 그렇게 하실 필요는 없지만 가능한 Git과 GitHub를 이용하여 Project의 버전관리를 하시는게 좋습니다.


 개발환경 서버를 이용한 Angular 프로젝트 실행

command 창을 열어 프로젝트 root로 working directory를 이동시킨 후 다음의 명령을 실행하면 Webpack을 이용하여 우리 소스를 bundling하고 로컬 웹서버를 이용하여 우리 프로젝트를 서비스하게 됩니다.

ng serve

명령 수행이 끝나면 webpack: Compiled successfully. 메시지가 출력됩니다. 이제 browser를 실행시켜 다음 URL로 접속해 정상적으로 출력되는지 확인하시면 됩니다.

http://localhost:4200

참고로 아래와 같이 --o option을 이용해서 ng serve를 실행시키면 default browser를 실행시켜서 해당 URL에 접속해 결과를 쉽게 확인할 수 있습니다.

ng serve --o

Angular project run


이번 포스트에서는 Angular application을 개발하기 위한 개발환경을 구축했습니다. 우리 강좌에서는 Testing과 관련된 사항은 다루지 않을 예정입니다. Testing과 관련된 사항은 추후에 다른 포스트에서 다루도록 하겠습니다.

이제 기본으로 만들어진 MySearchProject application을 조금씩 수정하면서 우리의 Angular 프로그램을 완성해 나가면 될 듯 합니다.

728x90
반응형

'Web Programming > Angular - TypeScript' 카테고리의 다른 글

Angular @Input 데이터공유  (0) 2018.08.28
Angular Material Table  (0) 2018.08.28
Angular 예제 따라하기  (0) 2018.08.28
SPA형식의 Web Application  (0) 2018.08.28
Angular 소개  (0) 2018.08.28
728x90
반응형

 Angular Version

Angualr의 History와 개요부터 간단하게 살펴보겠습니다.

Angular는 JavaScript based Open Source Front End Web Application Framework 입니다. 초기 버전인 AngularJS는 2010년 발표되었습니다. 지금은 Angular 1이라고 표현하기도 합니다. 버전 정책이 AngularJS 1.x로 올라가는 것이죠. 그렇게 발전해오다가 2016년 9월에 Angular 2가 정식으로 release되었습니다. 그러면서 Angular 2라고 명시하지 않고 Angular라는 이름으로 호명하기로 결정합니다. 지금 우리가 Angular라고 부르는 것은 모두 Angular 2 이후 버전입니다. 2017년 3월에 Angular 4가 release되었고 현재(2018년 1월)기준으로 Angular 5 까지 나온 상태입니다.

2017년 12월 3일부로 다음의 사항들이 정식으로 release되었습니다.

  • Angular 5.1.0
  • Angular CLI 1.6.0
  • Angualr Material
  • Angular Material CDK(component dev kit)

정리를 하자면 AngularJS라고 표현되는 Angular 1은 버전이 AngularJS 1.0, AngularJS 1.1, AngularJS 1.2, … 이렇게 올라가고 Angular라고 표현되는 Angular 2는 버전이 Angular 2.x.x, Angular 3.x.x, Angular 4.x.x, … 이렇게 올라갑니다. Angular 3는 Router issue때문에 release가 최소되었습니다. 그래서 Angular 2 다음 Major 버전이 Angular 4가 됩니다. 2017년 11월에 release된 Angular 5는 Angular 2의 3번째 Major 배포판 이라는 말이지요.

Angular는 유의적버전(SemVer)을 도입해서 버전 체계를 Major.Minor.Patch로 표현합니다. 즉, Angular 5.2.4 이렇게 표현하는 것이지요. 6개월을 기준으로 1회의 Major, 3회의 Minor 그리고 주단위로 패치가 실시되고 있습니다. Major Release는 Breaking Change 가 포함될 수 있습니다. Breaking Change란 이전버전과 호환성이 없는 변화를 지칭합니다. 따라서 시간이 좀 지나면 지금의 Angular와 또 많이 다른 모습의 Angular가 될 확률도 있습니다. 물론 Google에서는 가능한 그런 경우를 없앤다고 발표했지만 모를일이죠.

기존의 AngularJS와 지금의 Angular는 Architecture측면이나 구현측면에서 큰 차이가 있습니다. 그렇기 때문에 Angular 2 architecture가 발표되었을 때 많은 AngularJS 개발자들이 황당해 했던것도 사실입니다. 여하간 AngularJS는 역사속으로 사라지고 있습니다. 사실 Google에서도 AngularJS 시절에는 내부적으로 AngulraJS를 사용하지 않았습니다. 하지만 Angular로 넘어오면서 자사의 개발자체도 Angular로 진행하고 있고 Angular를 단지 web framework에서만 사용하는 기술이 아닌 모든 platform에 대응할 수 있는 형태로 발전시키고 있습니다.

다음은 기존의 AngularJS와 지금의 Angular의 중요 차이점 중 몇가지 입니다.

  • AngularJS의 Controller와 $scope 기반 개발방식에서 Angular의 컴포넌트 기반 개발방식(CBD, Component Based Development)으로 개발방법 변경되었습니다.
  • Angular의 주력 개발 언어로 TypeScript가 도입되었습니다.
  • Angular는 개발환경 지원도구인 Angular CLI를 제공합니다.

이외에도 더 많지만 일단 저 위의 3가지만 기억하시면 될 듯 합니다. 저 위의 3가지로 인해 개발 생산성과 성능면에서 큰 향상을 이루었습니다. 하지만 결정적(?)인 단점이 있습니다. Angular는 대부분의 browser를 지원하고 있는데 IE의 경우 9버전 이상부터 지원합니다. 따라서 Cross Browsing의 issue를 가지고 있습니다.

아참..로고도 바꾸었습니다. 테두리가 있는 방패모양의 로고에서 테두리를 빼고 A글자를 흰색으로 바꾸었습니다. ^^;;AngularJS to Angular

이 링크를 클릭해 보시면 Angular의 버전 업데이트에 대한 ChangeLog를 확인할 수 있습니다. 일 무지 열심히 하네요. 따라가기 힘들정도입니다.


 Angular 학습을 위한 pre-requisite

Angular는 Steep Learning Curve를 가집니다. 배우기가 힘들다는 거죠. 적어도 기본적인 JavaScript 개발에 대한 지식과 TypeScript에 대한 지식, 그리고 객체지향개발(OOP)에 대한 지식을 필수로 요구합니다. 물론 Angular를 배우면서 같이 하면 되긴 하지만 힘든건 사실입니다.

해서 Angular 강좌 역시 기본적으로 다음과 같은 선행지식을 필요로 합니다.

  • JavaScript
  • TypeScript
  • OOP(Object Oriented Programming)
  • Front End 개발 도구 ( npm, babel, webpack, gulp 등등)

참고로 이 링크에 가보시면 현재 Front End 개발환경에 대한 간단한 포스트를 보실 수 있습니다. 또한 이 링크에 가보시면 TypeScript에 대한 강좌 역시 보실 수 있습니다.

말은 어렵다고 했지만 하다보면 또 그냥 저냥 하게 됩니다. 일단 기본적인 소개는 이정도로 하고 개발환경부터 세팅해 보도록 하겠습니다.

728x90
반응형

'Web Programming > Angular - TypeScript' 카테고리의 다른 글

Angular @Input 데이터공유  (0) 2018.08.28
Angular Material Table  (0) 2018.08.28
Angular 예제 따라하기  (0) 2018.08.28
SPA형식의 Web Application  (0) 2018.08.28
Angular 개발환경세팅 하기  (0) 2018.08.28

+ Recent posts