위의 튜토리얼은 https://angular.io/tutorial 을 참고하였습니다.
1) Services
1-1. Why Services
-
컴포넌트는 오직 데이터를 보여주는 역할,
서비스는 데이터를 받아오는 역할
=> 이렇게 역할분담을 통하여 관리를 편리하게 하는게 목적임.
-
서비스를 통해서 여러 클래스간의 정보를 교환할 수도 있음.
ex) 서비스가 다른 서비스에게 메시지(데이터)를 보내는 것도 가능함.
1-2. Create the HeroService
HEROES 데이터를 받아올 역할을 맡을 HeroService를 만들어 봅시다.
ng generate service hero
기본 뼈대는 이런 모습입니다.
// hero.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class HeroService {
constructor() { }
}
Injectable
이라는 데코레이터가 자동으로 임포트되는데요. 이녀석의 역할은 우리 서비스를 Injectable
하게 만들어줍니다.
음.. 어렵게 생각하지 말고 그냥 다른 클래스에 데이터를 줄 수 있다는 뜻입니다.
1-3. Get hero data
이전 컴포넌트가 했던것 처럼 HEROES 데이터를 받아오는 기능을 만들어봅시다.
// hero.service.ts
import { Injectable } from '@angular/core';
import { Hero } from './hero';
import { HEROES } from './mock-heroes';
@Injectable({
providedIn: 'root'
})
export class HeroService {
getHeroes(): Hero[] {
return HEROES;
}
constructor() { }
}
이제 HeroService 객체를 어딘가에서 불러온다면, 그 객체의 getHeroes() 메서드를 사용하여
우리가 원하는 HEROES 배열을 사용할 수 있습니다.
1-4. Provide the HeroService
그 이전에, HeroService를 사용하기 위해서는 몇 가지 절차가 필요한데요.
일단 얘도 하나의 모듈이니까 등록을 해줘야합니다. 다만 provider에 등록을 해줍시다.
-
서비스를 임포트하고 provider에 등록한다.
등록은 module 파일에서 할 수 있다.
// app.module.ts import { HeroService } from './hero.service'; @NgModule({ declarations: [ ], imports: [ ], providers: [HeroService], // 추가 bootstrap: [AppComponent] }) export class AppModule { }
provider : 서비스를 만들거나 전달하는 역할을 하는 무언가..
-
injector에 서비스를 등록하기
@Injectable({ providedIn: 'root' })
이렇게 되어있으면 root에 등록된 서비스를 자식 컴포넌트들이 사용할 수 있는 것이다.
1-5. Update HeroesComponent
이제 Heroes 컴포넌트에서 Hero 서비스를 통해서 데이터를 받아야 합니다.
밑에서 적을 코딩 패턴이 약간 낯설 수 있는데, singleton 패턴과 관련이 있습니다.
-
HeroService 객체를 만든다
-
이 객체를 통해서 getHeroes 메서드를 사용하고 데이터를 받는다.
constructor(private heroService: HeroService) { } getHeroes(): void { this.heroes = this.heroService.getHeroes(); }
-
ngOnInit을 통해서 부른다
ngOnInit() { this.getHeroes(); }
그런데 생각해보면 constructor 안에서 부를 수도 있는데, 왜 굳이 이런 메서드를 만들고 ngOnInit 안에서 getHeroes를 시행할까??
=> lifecycle hook이랑 관련이 있습니다.
ex) 이런식으로 콘솔출력을 해보면,
constructor(private heroService: HeroService) {
console.log('constructor');
}
getHeroes(): void {
this.heroes = this.heroService.getHeroes();
}
ngOnInit() {
console.log('ngOninit');
this.getHeroes();
}
ngOnInit이 나중에 실행되는 것을 알 수 있습니다.
(vue에서도 created, beforeMount같은 요소들이 있듯이 angular에서도 생성자와 ngOnInit가 선후관계가 있습니다.)
나중에는 이런 선후관계가 매우 중요하기 때문에 신경쓰는게 좋습니다.