문제상황
앵귤러2 에서 일반적으로 자식 컴포넌트가 부모 컴포넌트에게 데이터를 전달하는 방법은 Output 과 EventEmitter 를 이용한 방법을, 부모 컴포넌트가 자식 컴포넌트에게 데이터를 전달하는 방법은 자식컴포넌트 선택자에 단지 속성으로 변수를 넘긴 후 Input 을 사용하여 받는다. 즉 뷰템플릿이 데이터 전송의 매체가 되는 셈.
하지만 문제가 복잡해져 서로 거리가 먼 컴포넌트 간의 통신을 해야하는 경우가 생김.
마치 나와 큰아빠와 큰아버지와 사촌동생 간에 동시에 데이터를 공유해야 하는 상황이라면?
1. 매개자 역할의 서비스 생성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import { Injectable } from '@angular/core'; import { Subject, Observable } from 'rxjs'; @Injectable() export class DataService { private subject = new Subject<any>(); constructor() { } sendData(data){ this.subject.next(data); console.log("sendData() data : " , data); } getData(){ return this.subject.asObservable(); } } | cs |
rxjs 의 Subject 객체는 Observable 인 동시에 Observer. 한 컴포넌트에서 서비스의 sendData() 를 호출하여 데이터를 Subject 의 next 메서드를 통해서 데이터 스트림에 밀어넣는다.
다른 getData() 메서드는 데이터를 받을 컴포넌트에서 호출하여 데이터스트림에서 Observable 객체를 받은 후, 데이터 전송이 완료되었을 때 구독(subscribe) 할 것이다.
2. 데이터를 보낼 컴포넌트
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | import { Component, OnInit, OnDestroy } from '@angular/core'; import { PostService } from '../../services/post/post.service'; import { DataService } from '../../services/data.service'; import { Post } from '../../models/post'; import { ActivatedRoute, Params } from '@angular/router'; import { Subscription } from 'rxjs/Subscription'; @Component({ selector: 'app-post', templateUrl: './post.component.html', styleUrls: ['./post.component.css'] }) export class PostComponent implements OnInit, OnDestroy { private subscription: Subscription; post: Post; postNo: number; constructor(private activatedRouter: ActivatedRoute, private postService: PostService, private dataService: DataService) { this.subscription = activatedRouter.params.subscribe((params: Params) => { this.postNo = params['postNo']; this.postService.getPost(this.postNo) .subscribe( (post) => { this.post = post; dataService.sendData(this.post); }, (error) => { console.log(error); } ); }); } ngOnInit() { } ngOnDestroy() { this.subscription.unsubscribe(); } } | cs |
좀 복잡해 보이지만 핵심은 단지 위에서 생성한 service 의 sendData() 를 호출하는 것. 참고로 subscription 객체는 구독했던 객체를 파괴하기 위해 사용. ngOnDestroy() 라이프사이클에서 저장했던 subscription 을 unsubscribe 해주면 된다.
DataService 를 주입받고, 보내고자 하는 데이터를 dataService.sendData() 로 호출하여 넘겨준다.
3. 데이터를 받을 컴포넌트
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | import { Component, OnInit, OnDestroy } from '@angular/core'; import { DataService } from '../../services/data.service'; import { Subscription } from 'rxjs/Subscription'; @Component({ selector: 'app-banner', templateUrl: './banner.component.html', styleUrls: ['./banner.component.css'] }) export class BannerComponent implements OnInit, OnDestroy { title = 'Blog'; regDate = ''; categoryName = ''; subscription: Subscription; constructor(private dataService: DataService) { console.log("banner 컴포넌트 생성!"); this.subscription = dataService.getData().subscribe(data => { console.log("banner subscription : " , data); this.title = data.title; this.regDate = data.regTime; this.categoryName = data.categoryId; }) } ngOnInit() { } ngOnDestroy(){ this.subscription.unsubscribe(); } } | cs |
데이터를 수신할 컴포넌트에서도 마찬가지로 Subscription 객체를 이용해 구독한 객체를 파괴시켜주어야 하며, DataService 를 주입받고, 이 DataService 의 getData() 메서드를 호출하여 Observable 객체를 받는다. 이를 subscribe 메서드를 사용하여 데이터가 전달되면 수행할 작업을 진행하면 된다.
'Javascript > Angular2' 카테고리의 다른 글
[Angular2] Angular Life Cycle Hooks (0) | 2018.05.29 |
---|---|
[Angular2] How to use reactive form in angular2 앵귤러2 폼 (0) | 2018.04.29 |
[Angular2] nginx 포트포워딩에 의한 앵귤러 서비스 url 경로문제 (0) | 2018.04.13 |