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