아 그거 뭐였지

[Angular] 자바스크립트 뒤로가기 데이터 유지 본문

Front-End

[Angular] 자바스크립트 뒤로가기 데이터 유지

승발자 2022. 1. 9. 20:57
728x90
반응형

※ 2022년 03월 14일 내용이 너무 빈약하여 수정하였습니다. ※

Q. 뒤로 가기해도 데이터 위치 유지 해주세요

쇼핑몰 프로젝트 진행 중.

상품 리스트 클릭후 뒤로 가기 시 해당 상품으로 포커싱이 되게 해 달라는 요청이 있어 작업하게 되었다.

해당 방법외에도 여러 가지 방법이 있으니 이 코드가 정답이 아니라는것을 유의하길 바란다. 책임회피 해버리기~

처음에는 localstorage를 사용해서 구현하였는데, 브라우저를 종료시켜도 데이터가 남아있는 경우가 있어

sessionstorage를 사용하여 구현하였다.

더보기

localstorage : 로컬에서 직접 삭제하기 전까지는 데이터가 남아있음

sessionstorage : 세션을 종료하기 전까지는 (ex_ 브라우저 창 닫기) 데이터가 남아있음

아이디어는 다음과 같다.

1. 뒤로 가기 이벤트가 아닐 시 async 요청 후 sessionstorage에 상품 리스트 데이터와 start값 저장

  • 더보기 요청시(또는 페이지네이션) start값이 필요하므로 상품 리스트 데이터와 start값을 같이 저장해준다.

2. 상품 리스트에서 상품 클릭 시 상품 위치 값을 sessionstorage에 저장

3. 클릭된 상품에서 뒤로 가기로 상품 리스트에 왔을 시 async 요청을 하지 않고 sessionstorage 데이터 호출

  • 클릭된 상품에서 뒤로 가기 이벤트 발생 시 sessionstroage에 체크 (true)
  • sessionstorage에서 상품 데이터를 가져와서 렌더링하고 상품 위치 값을 가져와서 포커싱

4. sessionstroage에서 렌더링이 끝났으면 sessionstroage에 체크 (false)

  // product-list component
  
  isBack = false;
  localBackItems = [];
  isMore = false;
  start = 0;
  products = [];
  
  getBackDatas(){
    // 뒤로가기로 해서 온건지 확인
    this.isBack = JSON.parse(sessionStorage.getItem('isMainBack'));
    //sessionstroage에서 데이터 가져오기
    let backItems = JSON.parse(sessionStorage.getItem('backMainItems'));
    //start값
    let index = parseInt(sessionStorage.getItem('backMainIndex'));
    //뒤로가기시 포커싱 되어야할 상품 위치
    //뒤로가기로 해서 온것이아니라면 그냥 0값을주어 최상단으로 위치한다.
    let scroll = parseInt(sessionStorage.getItem('mainScrollY')) ? JSON.parse(sessionStorage.getItem('mainScrollY')) : 0;
    //뒤로가기로 해서 왔을경우 sessionstroage값을 렌더링 후 해당 위치로 포커싱
    if(this.isBack && !this.isMore){
      this.products = backItems;
      this.localBackItems = backItems;
      this.goTab(scroll)
    }
    // 더보기 버튼 눌렀을경우 start값 적용해서 기존의 async요청
    // start는 데이터 Get요청할때 어디서부터 가져오는지를 뜻한다. 
    else if(this.isMore){
      this.start = index;
      this.getrProducts();
    }
    //뒤로가기로 해서 온것이 아닐경우 기존의 async요청
    else{
    //더보기시 데이터를 적재하는 방식으로 구현해서 products을 클리어해주어야함.
    //products는 getrProducts를 요청했을때 받아온 상품목록 데이터이다
      this.products=[];
      this.getrProducts();
    }
    //이부분이 없으면 새로고침을해도 sessionstroage데이터를 가져옴
    sessionStorage.setItem('isMainBack',JSON.stringify(false));
 }
 
  // 상품을 클릭했을때 이 함수를 콜한다.
  // 상품위치를 저장하는 함수이다.
  scroll:nubmer
  @HostListener("window:scroll",['$event'])
  onScroll(){
    this.scroll = window.pageYOffset
    sessionStorage.setItem('mainScrollY',JSON.stringify(this.scroll));
  }

???: 아니 뒤로가기 이벤트는 어떻게 감지함? 그걸 빼먹으면 어떡함!

바로 밑에 준비되어있다.

  // product-detail component
  // Angular에서 사용되는 HostListener이다.
  // import { HostListener} from '@angular/core'; 로 import해주어야함
  // 뒤로가기 이벤트 발생시 sessionstroage에 체크한다.
  
  @HostListener('window:popstate',['$event'])
  onBack(e:Event){
    sessionStorage.setItem('isMainBack',JSON.stringify(true));
  }

Angular에서는 HostListener를 사용하여 쉽게 뒤로가기 이벤트를 감지할수있다.

Angular가 아닌 자바스크립트에서는

//product-detail component

window.onpageshow = function(e){
	if(e.persisted){
    	//뒤로가기 눌렀을때 로직실행
    	sessionStorage.setItem('isMainBack',JSON.stringify(true));
      }
 }

이런식으로 사용하면 될것같다.

 

상품리스트를 받아온후 HTML에서 뒤로왔을때와 아닐때를 구분해서 상품리스트를 보여주면 완성이다.

<!-- 뒤로가기인지 체크해서 캐시데이터 사용할것인지 api데이터 사용할것인지 결정 -->
<ng-container *ngFor="let item of isBack ? localBackItems : products;">
	<div class="list-wrap" mat-ripple>
    	<!-- 상품데이터 출력하는 html -->
      	{{item.name}}
	</div>
</ng-container>
728x90
반응형
Comments