Loading Bar 만들기(Angular Material)

소스코드

이 게시물에는 코드작성이 포함되어 있습니다. 소스코드를 받으신 후 진행해 주세요. MEAN Stack/개발 환경 구축에서 설명된 프로그램들(git, npm, atom editor)이 있어야 아래의 명령어들을 실행할 수 있습니다.

이 게시물의 소스코드는 기본사이트 만들기 / Resolve 사용하기에서 이어집니다.

angular-site.git 을 clone 한 적이 있는 경우: 터미널에서 해당 폴더로 이동 후 아래 명령어들을 붙여넣기합니다. 폴더 내 모든 코드가 이 게시물의 코드로 교체됩니다. 이를 원치 않으시면 이 방법을 선택하지 마세요.

git reset --hard
git pull
git reset --hard 974e233
git reset --soft 4944e19
npm install
atom .

angular-site.git 을 clone 한 적이 없는 경우: 터미널에서 코드를 다운 받을 폴더로 이동한 후 아래 명령어들을 붙여넣기하여 angular-site.git 을 clone 합니다.

git clone https://github.com/a-mean-blogger/angular-site.git
cd angular-site
git reset --hard 974e233
git reset --soft 4944e19
npm install
atom .

- Github에서 소스코드 보기: https://github.com/a-mean-blogger/angular-site/tree/974e233da79f3920a757d41199ef147d52301ec4


로딩바는 다른 것이 아니라 뭔가 시간이 걸리는 작업이 일어나는 지점에서 로딩중임을 알리는 무언가를 보여줬다가 작업이 끝나는 지점에서 그 무언가를 숨기는 것입니다.

이전 강의를 통해 Users 메뉴 클릭 -> Resolve에서 API 호출 -> 페이지 이동 으로 작업이 이루어지게 되면서 API가 여러가지 이유로 지연되는 경우, 사용자가 이를 알 수 있도록 로딩바를 보여주도록 합시다.

로딩바는 직접 만들어도 되지만, Angular Material 를 써보도록 합시다.

Angular Material

Angular material은 Angular의 공식 design components package입니다. (공식 사이트: https://material.angular.io) from controls, navigation, layout, button & indicators 등등의 component를 제공합니다. 공식사이트에 가면 각각의 component 예제가 있으니 미리 보고 마음에 드는 것이 있다면 이 package를 사용하시면 되겠습니다.

이번 강의에 사용될 Angular material의 component는 Button & Indicator 항목의 Progress bar입니다.(https://material.angular.io/components/progress-bar/overview)

Package 설치

아래 명령어를 입력하여 Angular Material package와 Angular CDK package를 설치합니다.

$ npm install --save @angular/material @angular/cdk

만약 @angular/animations package가 설치되어 있지 않다면(package.json의 dependencies에 이 항목이 없다면) 아래 명령어로 Angular Animation package도 설치해 줍니다.

$ npm install --save @angular/animations

폴더 구조


주황색은 변경된 파일, 녹색은 새로 생성된 파일, 회색은 변화가 없는 파일입니다.

코드

// src/app/app.module.ts

//...생략
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { MdProgressBarModule } from '@angular/material'; //1

//...생략

@NgModule({
  //...생략
  imports: [
    //....생략
    ReactiveFormsModule,
    MdProgressBarModule, //1
  ],
  //...생략
})
export class AppModule { }

1. app.module.ts에 Angular Material Module들 중 이번 강의에서 사용할 MdProgressBarModule을 넣어줍시다. 어떤 module이 필요한지는 공식 문서 사이트의 progress bar 항목(https://material.angular.io/components/progress-bar/api)에 표시된 directive 이름(MdProgressBar)에 "Module"을 붙여주면 됩니다. 다른 항목을 추가하고 싶다면 해당 directive 이름에 "Module"을 붙여주면 되겠지요.

/* /src/styles.css */
@import "[email protected]/material/prebuilt-themes/indigo-pink.css"; //1

body {
  color: #0C2E2B;
}

1. styles.css에 @import "[email protected]/material/prebuilt-themes/indigo-pink.css"를 넣어줍니다. 이때  indigo-pink는 Anagular Material의 theme 이름입니다. default theme을 바꾸거나 custom theme을 사용하는 법은 https://material.angular.io/guide/theming 를 참고합니다.

이제 Angular Material을 사용할 준비가 되었습니다.

다음으로 app.component입니다.

// src/app/app.component.ts

import { Component } from '@angular/core';
import {
  Router,
  Event as RouterEvent,
  NavigationStart,
  NavigationEnd,    //1
  NavigationCancel, //1
  NavigationError,  //1
} from '@angular/router'

import { AuthService } from './auth.service';

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

  constructor(
    private router: Router,
    public authService: AuthService,
  ) {
    router.events.subscribe((event: RouterEvent) => {
      this.refreshToken(event);
      this.updateLoadingBar(event); //4
    });
  }

  //...생략

  private updateLoadingBar(event: RouterEvent): void { //3
    if (event instanceof NavigationStart) {
      this.loading = true;
    }
    if (event instanceof NavigationEnd
      || event instanceof NavigationCancel
      || event instanceof NavigationError) {
      this.loading = false;
    }
  }

}

로딩바는 <메뉴의 클릭>과 <페이지 이동> 사이에 보여주어야 합니다. 이때 <메뉴의 클릭>을 Angular의 Event중 NavigationStart로, <페이지 이동(완료)>를 NavigationEnd로 생각하고 이 이벤트에서 변수의 값을 변경함으로 html template에서 그 변수의 값으로 로딩바를 보여주고 숨길 수 있게 하는 코드입니다.

1. 페이지 이동이 정상적으로 이루어진 경우 NavigationEnd지만, NavigationCancel, NavigationError 역시 로딩바를 그만보여줘야 할 이벤트들입니다. (router의 전체 이벤트 항목은 https://angular.io/api/router/Event 에서 보실 수 있습니다)

2. loading 이라는 변수를 만들었습니다. 이 값을 navigation 상태에 따라 바꾸어 주고 html template에서 이 값을 기준으로 로딩바를 보이고 숨기게 됩니다.

3. navigation의 상태를 확인하고 loading의 값을 바꿔주는 함수입니다.

4. route의 이벤트 변경이 있을때마다 3번의 함수를 실행시킵니다.

<!-- src/app/app.component.html-->

<md-progress-bar //1
  *ngIf="loading" //2
  class="loading-overlay" //3
  [mode]="'indeterminate'" //4
></md-progress-bar>

<!-- ...생략 -->

html template의 첫줄에 위와 같이 넣어줍니다.

1. md-progress-bar는 Angular Material에 정의된 component입니다. 로딩 애니메이션이 저장되어 있습니다. 2. loading이 true인 경우에만 보여줍니다.
3. css를 위한 class이름입니다.
4. indeterminate mode로 보여줍니다. 다른 모드들은 https://material.angular.io/components/progress-bar/examples 에서 볼 수 있습니다.

/* src/app/app.component.css */

.loading-overlay{
  position: fixed;
  top: 0px;
  width: 100%;
  z-index: 1;
}

 로딩바를 항상 페이지 가장 위에 보여주기 위한 css입니다.

실행 결과

Angular-CLI 명령어 사용해서 서버를 실행합시다. 

ng serve --open

로그인을 하고 Users 메뉴를 클릭해봅시다.

페이지 상단에 로딩바가 잠시 보였다가 사라지면서 Users 페이지로 넘어가게 됩니다.

마치며..

다음 강의는 마무리로 user의 나머지 기능들(show, edit)를 넣어 사이트를 완성하겠습니다.

댓글

J
JeongHwan Kim 2018.03.18
Md는 depricated 되었고 Mat으로 바꾸래요!
I
Ian H 2018.03.22
@JeongHwan Kim,
알려주셔서 감사합니다^^  강의 본문은 시간이 나는대로 고치도록 하겠습니다.
댓글쓰기

이 글에 댓글을 다시려면 SNS 계정으로 로그인하세요. 자세히 알아보기

UP