본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


앵귤러, 리엑트, 뷰/Angular Tutorial(old)

앵귤러 튜토리얼 (Angular tutorial) -20 with 파이어 베이스

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2019. 7. 12.

* 제가 다시 작성한 최신 튜토리얼 수정본 입니다. 아래 주소를 통해서 진행하시는 것을 권장 드립니다. ^^

lts0606.tistory.com/328

 

앵귤러 튜토리얼(Angular tutorial) - 1

안녕하세요. 앵귤러에 대해서 알아보기위해 이곳을 찾아주신 분 들께 감사의 말씀 드립니다.^^ 천천히, 초심자도 조금 더 쉽게 접근할 수 있도록 내용을 구성하여 보겠습니다. 어��

lts0606.tistory.com

 

이번시간에는 수정에 대해서 먼저 알아보도록 하겠다.
여기서 핵심 내용은 map 이라 할 수 있다.
Javascript에서의 map은 배열의 값을 변경하는데 사용된다.

아래는 자바스크립트 코드 예제이다.

var array1 = [1, 4, 9, 16];
// pass a function to map
const map1 = array1.map(x => x * 2);
console.log(map1);
// expected output: Array [2, 8, 18, 32]

 

마찬가지로 앵귤러에서도 map의 이름을 가진 함수는 저장되어 있는 데이터를 변경할 때 사용 된다.
이제 만들어볼 파이어베이스 데이터베이스 수정 함수는 아래단계를 통해 이루어져 있다.
1. 컬렉션 객체를 가져온다.
2. 컬렉션 객체에서 수정할 대상을 가져온다.
3. 수정할 대상을 바꾼 뒤 구독행위를 시작한다.
4. 만약 데이터 조회하는 함수가 존재하면 수정 뒤 구독하는 행위를 종료한다. (2중구독이 되므로)

 

수정함수 내용을 먼저 살펴보자.

  updatItem(db_name : string, param: any){
    var subscription = this.getCollections(db_name).stateChanges().pipe(map( changes => { //pip 함수는 map 함수를 붙여주는 역할을 한다.
      return changes.map(a=>{  //map 함수는 데이터의 내용을 바꾸는 역할을 한다.
        const data = a.payload.doc.data() as any;
        const ID = a.payload.doc.id; //고유 아이디 값
        this.getCollections(db_name).doc(ID).update(param);  //id 값을 통해 수정한다.
        return data;
      });
    })).subscribe((oo)=>{  //해당 수정행위를 구독한다.
      subscription.unsubscribe();  //getItem 함수를 통해 구독을 하고 있기 때문에 여기서 수정한 구독행위는 바로 종료시킨다.
                                   //만약 해당 구독행위를 종료하지 않으면 구독행위가 다중 발생하여 무한loop 수정 행위가 발생한다.
    });
  }

와...내용이 무척 어렵다.
stateChanges 라는 함수는 해당 컬렉션에서의 이벤트를 관찰하는데(데이터의 변동) 사용된다. pip 함수는 map, filter같은 함수를 사용 할 수있게 해주는 함수이다.

pip로 연결된 map 함수를 활용해서 컬렉션의 데이터를 가져와서 변경하는 내용이 핵심이라 할 수 있다.


음..내용이 어렵다면 일단 지금은 "공식"이다 라고 생각하는 편이 나을 것 같다. 
앞으로 이러한 문법과 내용을 자주 만나다보면 익숙해져 이해하기 쉬울 것 이다.

가장 중요한 것은 unsubscribe() 함수를 통해서 수정하는 구독행위를 종료한 점이다. 
뭔지 모르겠지만 수정이나 삭제 행위를 한 경우에 해당 구독 행위는 "종료" 해야 된다고 생각하자.


아래는 app.component.ts 의 최종 모습 코드이다.

import { Component } from '@angular/core';

import { AngularFirestore, AngularFirestoreCollection } from '@angular/fire/firestore';
import { BehaviorSubject } from 'rxjs';
import { AngularFireStorage} from '@angular/fire/storage';

import { map } from "rxjs/operators"; // map이다.

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'testFire';
  //데이터 베이스 관련 객체
  private DataBase : AngularFirestore;

  //컬렉션을 담아두는 배열
  private collections = new Array();

  //나중에 쓸 저장소 관련 객체
  private storage : AngularFireStorage;

  //의존성 주입
  constructor(db : AngularFirestore,strg : AngularFireStorage) {   //모듈에서 만들어진 파이어 베이스 접속관련 객체
    this.DataBase = db;
    this.storage = strg;

    this.getItem('board').subscribe((res)=>{  //리스트를 조회하는 구독행위
      console.log(res);
    });
    setTimeout(() => {
      this.updatItem('board',{test:1234});  //데이터 수정
    }, 5000);
  }  

  //컬렉션이 있는지 조사해서 해당 내용을 리턴하는 함수
  getCollections (db_name : string) : AngularFirestoreCollection<any>{
    var result = this.collections[db_name];  //배열에 값을 확인
    if(result == undefined || result == null){  //배열에 값이 비어있다면
      this.collections[db_name] = this.DataBase.collection<any>(db_name, (ref) =>ref);   //새로 만들어준다.
      result = this.collections[db_name];
    }
    return result;
  }

  getItem(db_name : string){
    var items : BehaviorSubject<any[]> = new BehaviorSubject([]);
    this.getCollections(db_name).valueChanges().forEach((val)=>{  //데이터를 가져오기
      items.next(val); 
    });    
    return items; 
  }

  setItem(db_name : string, param : any){  //데이터 등록
    this.getCollections(db_name).add(param);  
  }


  updatItem(db_name : string, param: any){
    var subscription = this.getCollections(db_name).stateChanges().pipe(map( changes => { //pip 함수는 map 함수를 붙여주는 역할을 한다.
      return changes.map(a=>{  //map 함수는 데이터의 내용을 바꾸는 역할을 한다.
        const data = a.payload.doc.data() as any;
        const ID = a.payload.doc.id; //고유 아이디 값
        this.getCollections(db_name).doc(ID).update(param);  //id 값을 통해 수정한다.
        return data;
      });
    })).subscribe((oo)=>{  //해당 수정행위를 구독한다.
      subscription.unsubscribe();  //getItem 함수를 통해 구독을 하고 있기 때문에 여기서 수정한 구독행위는 바로 종료시킨다.
                                   //만약 해당 구독행위를 종료하지 않으면 구독행위가 다중 발생하여 무한loop 수정 행위가 발생한다.
    });
  }
}

 

결과 사진이다.

 

마찬가지로 수정행위를 한 것 뿐인데 getItem에서 콘솔이 자동으로 실행이 되었다.
수정행위가 2번 된 것은 데이터가 2개가 들어있었기 때문이다. 
해당부분을 이제 조건을 통해서 수정가능하게 하면 될 것이다.

 

이번시간에서 가장 중요한 점을 간단히 정리하여 보자.

내용은 짧지만 어렵다.

 

1. 수정을 하기위해서는 컬렉션 객체를 가져와야 한다.

2. 해당 컬렉션에서 stateChanges 함수를 통해서 하위 내용을 가져와야 한다.

3. pip 함수를 통해 데이터에 접근하도록 map 함수를 등록하여 준다.

4. map 함수에서 하고자 하는 내용을 작성한다.

5. 해당 수정 메소드를 subscribe(구독) 한다.

6. 구독을 한 뒤에 이미 해당 컬렉션이 구독(getItem함수) 중이므로 수정행위를 통한 구독은 unsubscribe한다.

다음시간에는 삭제 기능에 대해서 알아보도록 하겠다.

src.zip
0.01MB

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글