[Day25] 칸반보드 - Drag & Drop 방식과 기존 코드 비교 (240726)

2024. 7. 26. 18:17공부/DGTP TIL

const ordersMap = cardIds.reduce((map, id, index) => {
      map[id] = index + 1;
      return map;
    }, {});

기존의 정렬 방식. 나름 짧고 간결하게 잘 짰다 생각하지만, 사용감 자체는 별로였다(직접 정렬하고 싶은 index들과 정렬하고 싶은 상태로 숫자들을 입력시켜야 했기 때문에 오류가 많았다.)

 

============================================================================================

function getSavedColumns() {
    if (localStorage.getItem("backlogItems")) {
        backlogListArray = JSON.parse(localStorage.backlogItems);
        // 다른 Array들
    } else {
        // 기본값 설정
    }
}

// 로컬스토리지에 저장
function updateSavedColumns() {
    listArrays = [backlogListArray, progressListArray, completeListArray, onHoldListArray];
    const arrayNames = ["backlog", "progress", "complete", "onHold"];
    arrayNames.forEach((arrayName, index) => {
        localStorage.setItem(`${arrayName}Items`, JSON.stringify(listArrays[index]));
    });
}

각 칼럼의 항목들을 배열로 관리하고, localStorage를 사용하여 데이터를 저장하고 불러오고 있다.

 

function updateDOM() {
    if (!updatedOnLoad) {
        getSavedColumns();
    }
    
    backlogListEl.textContent = "";
    backlogListArray.forEach((backlogItem, index) => {
        createItemEl(backlogListEl, 0, backlogItem, index);
    });
    // 다른 칼럼들에 대해서도 반복

    updatedOnLoad = true;
    updateSavedColumns();
}

function createItemEl(columnEl, column, item, index) {
    const listEl = document.createElement("li");
    listEl.textContent = item;
    listEl.id = index;
    listEl.classList.add("drag-item");
    listEl.draggable = true;
    listEl.setAttribute("onfocusout", `updateItem(${index}, ${column})`);
    listEl.setAttribute("ondragstart", "drag(event)");
    listEl.contentEditable = true;
    columnEl.appendChild(listEl);
}

저장된 데이터를 기반으로 DOM을 업데이트. (이전 과정에서 선언한 getSaveColumn 사용)

각 항목에 대해 createItemEl 함수를 호출하여 DOM 요소를 생성하고 추가.

 

function drag(e) {
    draggedItem = e.target;
    dragging = true;
}

function allowDrop(e) {
    e.preventDefault();
}

function drop(e) {
    e.preventDefault();
    const parent = listColumns[currentColumn];
    listColumns.forEach((column) => {
        column.classList.remove("over");
    });
    parent.appendChild(draggedItem);
    dragging = false;
    rebuildArrays();
}

function rebuildArrays() {
    backlogListArray = Array.from(backlogListEl.children).map(item => item.textContent);
    // 다른 칼럼들에 대해서도 반복
    updateDOM();
}

 

  1. 접근 방식:
    • 이전 코드: 아이템의 순서를 객체(맵)로 관리. 각 아이템의 ID를 키로, 순서를 값으로 저장.
    • 현재 코드: DOM 요소를 직접 조작하고, 배열을 사용하여 순서를 관리.
  2. 데이터 구조:
    • 이전 코드: 객체(맵)를 사용하여 ID와 순서를 연결.
    • 현재 코드: 배열을 사용하여 아이템의 순서를 관리.
  3. 기능:
    • 이전 코드: 순서 정보만 생성합니다. 실제 DOM 조작이나 드래그 앤 드롭 로직은 포함되어 있지 않음.
    • 현재 코드: 전체 드래그 앤 드롭 프로세스를 구현합니다. DOM 조작, 이벤트 처리, 데이터 갱신 등을 포함.
  4. 유연성:
    • 이전 코드: ID 기반으로 작동하므로, 아이템의 고유 식별자가 필요.
    • 현재 코드: DOM 요소의 순서에 기반하여 작동하므로, 별도의 ID 관리가 필요 없음.
  5. 성능:
    • 이전 코드: 단순히 맵을 생성하므로 매우 빠름.
    • 현재 코드: DOM 조작과 배열 재구성을 포함하므로 상대적으로 더 많은 연산이 필요할.
  6. 사용 사례:
    • 이전 코드: 순서 정보만 필요한 경우에 적합. 서버에 순서 정보만 전송하는 경우에 유용.
    • 현재 코드: 실시간으로 UI를 업데이트하고 사용자 상호작용을 처리해야 하는 경우에 적합.

 

DB와 연결하기 위해서는 이전에 작성한 코드처럼 간단한 연산과 id만이 전송되는 방식이 적합하다.

그러나, 사용자 경험 향상을 위해 현재 코드의 drag and drop 로직을 채용하는 것은 고려할만한 사항이다.

drop이 진행된 다음 순서 정보를 업데이트 방식으로 처리할 수 있겠다.

function afterDrop() {
  const newOrderMap = {};
  listItems.forEach((item, index) => {
    newOrderMap[item.id] = index + 1;
  });
}