먹짱(쇼핑몰 프로젝트) - 어드민 페이지(1) - 여러 개의 js모듈 한 페이지에 띄우기

ryan·2022년 6월 6일
0

개요

이번 프로젝트에서 내가 담당한 페이지 중 하나인 어드민 페이지를 구현하는 과정에서 느낀 문제점과 그 해결 방법 그리고 그에 대한 스스로의 피드백을 작성해봤다.


만난 문제점

  • 어드민 페이지에 들어갈 기능은 '상품에 대한 CRUD'와 '주문 조회/취소'가 해당된다.

  • 지금까지는 하나의 페이지에 하나의 js로만 구현해봐서, 어드민 페이지처럼 한 페이지에 여러 기능을 넣는 것에 대한 설계 감각이 없었다.

  • 쉽게 생각해낼 수 있는 선택지는 2개이다.
    • 1) 기능 별로 페이지와 js를 따로 관리한다.
    • 2) 한 페이지에 여러개의 js 모듈을 둔다.

  • 나는 후자를 선택했다. 그 이유는 js를 모듈화 시키는 방법이 궁금했고, 사용자 경험에서도 한 페이지에서 기능단위로 자연스럽게 넘어가는 것(SPA처럼)이 더 나을 것이라고 생각했기 때문이다.

해결방법

파일 구조

  • adminPage.js에서 '상품CRUD', '주문 조회 기능'이 구현된 js모듈을 관리하는 형태이다.

  • 다른 팀원들도 많이 사용해야 하는 기능이라 최대한 가독성 있게 작성하려 노력했다. 한 페이지에서 다양한 모듈을 불러오기 때문에 모듈을 구분할만한 장치가 필요했고, flag 변수를 두는 것보다는 sessionStorage를 적극적으로 활용하여 동작를 브라우저로 나눠놓았다.

  • 모듈이 생성될 때마다 DOM요소를 계속 지우고 생성하는 형식으로 생각했는데, 코드의 복잡도가 올라가고 유지보수 그리고 버그에 비효율이 발생하는 것 같아서 reload와 onload를 통해 모듈의 노드를 띄우고 없애는 작업을 대신했다.

코드

코드 흐름

1) 각 기능 버튼을 누르면 세션 스토리지에 key는 'adminPagestate' , value는 해당 기능명이 등록된다.

2) 이미 등록된 기능이 있는 경우, 세션스토리지에서 지우고 새로 등록한다.

3) event target을 대조하여 맞는 모듈을 실행시킨다.(모듈은 DOM요소를 띄운다.)

4) 기능 버튼을 누르거나, 모듈 내의 기능이 실행되면(ex. 상품 등록 버튼을 누르면) 페이지 reload를 시킨다.

5) window.onload를 통해 reload됐을 경우, 마지막으로 눌렀던 기능의 모듈을 다시 한번 실행시킨다.(초기화시키는 개념)

// 모듈 불러오기
import showOrderedListModule from './adminOrderPage.js';
import showAddItemModule from './adminAddItem.js';
import showPathDelItemModule from './adminPatchDeleteItem.js';
import showItemListModule from './adminItemList.js';


const MODULES = {
  showOrderedList: 'showOrderedList',
  showAddItem: 'showAddItem',
  showPatchDelItem: 'showPatchDelItem',
  showItemList: 'showItemList',
};

// 버튼 별 핸들러 달기
$showAddItemBtn.addEventListener('click', setSessionNowPage);
$showOrderedListBtn.addEventListener('click', setSessionNowPage);
$showPatchDelItemBtn.addEventListener('click', setSessionNowPage);
$showItemListBtn.addEventListener('click', setSessionNowPage)


// 이벤트 핸들러 콜백
function setSessionNowPage(e) {
  let pageflag = e.target.id;
  if (sessionStorage.getItem('adminPagestate')) {
    sessionStorage.removeItem('adminPagestate'); // 다른 flag값이 있는 경우 삭제하고 다시 추가
    sessionStorage.setItem('adminPagestate', pageflag);
    return window.location.reload();
  }
  sessionStorage.setItem('adminPagestate', pageflag);
  if (pageflag === showOrderedList) return showOrderedListModule();
  else if (pageflag === showAddItem) return showAddItemModule();
  else if (pageflag === showPatchDelItem) return showPathDelItemModule();
  else if (pageflag === showItemList) return showItemListModule();
}


window.onload = () => {
  switch (sessionStorage.getItem('adminPagestate')) {
    case showOrderedList:
      showOrderedListModule();
      break;
    case showAddItem:
      showAddItemModule();
      break;
    case showPatchDelItem:
      showPathDelItemModule();
      break;
    case showItemList:
      showItemListModule();
      break;
    default:
      break;
  }
};

화면 예시


피드백

1. 각 기능의 버튼은 같은 콜백 함수를 사용하기 때문에 이전 포스팅에서 다뤘던 이벤트 위임을 활용할 수 있다.

2. 이후 포스팅에서 다룰 예정이지만, 각 모듈은 insertAdjacenthtml을 통해 DOM요소를 띄우고 관리하기 때문에 레이아웃에 변경사항이 발생했을 때 유지보수가 효율적이지 않다.

3. SPA처럼 구현하고 싶었지만 결국 기능을 이용하면 새로고침이 발생한다. 코드를 바꾸는 건 어렵겠지만 JS를 컴포넌트화 시켜서 다루는 방법에 대해 학습해봐야 한다.

4. 기능에 클릭 이벤트가 발생햇을 때 페이지를 초기화 시키는 방법이 reload, onload를 사용한 방법말고 없을까?

profile
프론트엔드 개발자

0개의 댓글