Angular2 Service
서비스는 @Injectable 장식자 ( = 주입 가능한 클래스라는 뜻 ) 를 추가한 클래스 이다.
@Injectable 을 생략한다고 해서 의존성 주입에 문제가 생기는 것은 아니지만, 생략하였을때 일반 클래스라 오인할 수 있기 때문에 반드시 추가해야 한다.
import { Injectable } from '@angular/core';
@Injectable()
export class HelloService {
sayHello(){
return "Hello 서비스!";
}
constructor() {}
}
===> hello.service.ts / HelloService 라는 서비스 생성
import { Component } from '@angular/core';
import { HelloService } from './hello.service';
@Component({
selector: 'hello',
template: ``,
providers: [HelloService]
// -> providers 로 서비스 선언한다.
})
export class HelloComponent {
welcome: string;
constructor(helloService: HelloService) {
this.welcome = helloService.sayHello();
} // -> 생성자에서 서비스 선언 후 사용 (추천)
constructor() {
let Hello = new HelloService();
this.welcome = Hello.sayHello();
} // -> 생성자에서 서비스 선언하지 않고 사용 (비추천 : 새로운 변수 생성 / 메모리 사용)
===> hello.component.ts
providers 에 사용할 서비스를 컴포넌트에서 HelloService 를 불러와 생성자에서 선언 후 사용.
생성자에서 선언하지 않고 let Hello = new HelloSerivce(); 로 사용가능.
- 객체지향 서비스
크게 부모 / 자식 클래스가 있고 자식 클래스에는 공통 메서드가 정의돼 있기 떄문에 공통 메서드를 제어할 수 있는 인터페이스를 정의한다.
import { Injectable } from '@angular/core';
@Injectable()
export class Parent {
getName(){
return "Parent 서비스!";
}
}
===> parent.service.ts / 부모 서비스
import { Injectable } from '@angular/core';
import { Parent } from './parent.service';
export interface Child {
getData();
}
@Injectable()
export class FirstChild implements Child {
constructor(public parent: Parent) { }
// -> Child 인터페이스만 사용하였기 떄문에 부모는 생성자에 선언하여 사용하여야 한다.
getData() {
return [
{ Child: 'FirstChild 서비스' },
{ parent: this.parent.getName() }
];
}
}
@Injectable()
export class SecondChild extends Parent implements Child {
getData() {
return [
{ Child: 'SecondChild 서비스' },
{ parent: super.getName() }
// -> 부모를 상속하였기 때문에 super 로써 사용가능하다.
];
}
}
===> child.service.ts / 자식 서비스
위의 예시처럼 First / Second 로 Parent 를 사용가능하지만
SecondChild 에서는 super 를 통하여 호출하기 때문에 다른 컴포넌트나 객체로 부모의 데이터를 전달 할수 없으나 FirstChild 에서 처럼 생성자에서 부모를 선언 후 사용한다면 전달이 가능하기 떄문에 extends 를 사용하는것 대신에 생성자에서 부모를 선언하여 사용하는 것이 바람직하다.
import { Component } from '@angular/core';
import { Parent } from './parent.service';
import { FirstChild, SecondChild } from './child.service';
@Component({
selector: 'oop-cmp',
template: `
생성자 주입방식<br>
<br>
상속방식<br>
`,
providers: [Parent, FirstChild, SecondChild]
})
export class OopComponent {
firstChildData;
secondChildData;
constructor(firstChild: FirstChild, secondChild: SecondChild) {
this.firstChildData = firstChild.getData();
this.secondChildData = secondChild.getData();
}
}
===> oop.component.ts / 컴포넌트
- 목 객체 서비스
서버 의존성 없이 데이터를 제공하기 위해 테스트 데이터를 정의한 객체이다.
목 객체를 사용하는 이유는 개발 과정에서 서버 의존성과 같은 외부 의존성을 제거함으로써 테스트를 가능하게 하기 위함이다.
export class User {
name: string;
id : string;
}
===> user.ts / User 데이터 객체
import { User } from './user';
export var USER: User[] = [
{name: '유비',id:'1'},
{name: '관우',id:'2'},
{name: '장비',id:'3'}
];
===> mock-user.ts / 테스트 데이터 객체 USER 생성
import { Injectable } from '@angular/core';
import { USER } from './mock-user';
export interface DataServiceStructure{
getUser();
}
@Injectable()
export class MockService implements DataServiceStructure{
constructor() {}
getUser(){
return USER;
}
}
===> mock.service.ts / 목 서비스 생성 : 테스트 데이터 USER 를 리턴하는 서비스 생성
import { Component, OnInit } from '@angular/core';
import { MockService } from './mock.service';
import { User } from './user';
@Component({
selector: 'mock',
template: `
<b>이름 출력</b>
<div *ngFor="let o of listUser">
|
</div>`,
providers: [MockService]
})
export class MockComponent {
listUser: User[];
// -> listUser 라는 리스트를 해당 User 라는 데이터 타입의 객체로 사용한다.
constructor(private userService: MockService) {
this.listUser = userService.getUser();
// -> MockService 를 선언하여 해당 USER 데이터를 불러와 저장함.
}
}
===> mock-component.ts / 해당 서비스와 데이터 타입 객체를 불러와 사용