zTree 비동기 로드 환경에서 전체 노드 검색 기능 구현하기

zTree는 방대한 양의 계층형 데이터를 렌더링할 때 뛰어난 성능과 유연성을 제공하는 JavaScript 트리 플러그인입니다. 데이터의 크기가 수만 개 이상으로 커질 경우, 초기 렌더링 부하를 줄이기 위해 점진적 비동기 로드(Async Load) 방식을 사용하는 것이 일반적입니다.

그러나 비동기 로드 방식을 적용하면 내장된 검색 기능인 getNodesByParamFuzzy 또는 getNodesByParam 메서드를 사용할 때 치명적인 제한이 발생합니다. 이 메서드들은 현재 메모리에 적재된 노드만 검색할 수 있기 때문에, 아직 비동기 요청이 이루어지지 않아 로드되지 않은 하위 노드는 검색 결과에서 누락됩니다.

이러한 문제를 해결하기 위해, 사용자 검색 시점까지 모든 노드가 백그라운드에서 자동으로 비동기 로드되도록 유도하고, 전체 로드가 완료된 것을 감지한 뒤 검색 로직을 실행하는 아키텍처를 설계할 수 있습니다.

1. 백그라운드 자동 비동기 로드 트리거

먼저, 노드의 비동기 로드가 성공할 때마다 호출되는 콜백 함수를 설정하여, 아직 자식 노드를 불러오지 않은(zAsync 속성이 false인) 노드를 탐색하고 강제로 로드 요청을 보냅니다.

function handleAsyncSuccess(event, treeId, node, response) {
    const treeInstance = $.fn.zTree.getZTreeObj(treeId);
    // 중첩된 JSON 구조를 1차원 배열로 평탄화하여 순회 성능을 높임
    const flattenedNodes = treeInstance.transformToArray(treeInstance.getNodes());
    
    flattenedNodes.forEach(currentNode => {
        // 아직 비동기 로드가 완료되지 않은 노드인 경우 자식 노드 로드 강제 실행
        if (!currentNode.zAsync) {
            treeInstance.reAsyncChildNodes(currentNode, null, true);
        }
    });
}

2. 트리 전체 로드 완료 대기 메커니즘

검색 기능은 트리의 모든 노드가 메모리에 적재된 후에 실행되어야 합니다. 이를 위해 PromisesetInterval을 활용하여 트리의 준비 상태를 비동기적으로 확인하는 유틸리티 함수를 구현합니다.

function waitForTreeInitialization(treeId) {
    return new Promise((resolve) => {
        const treeInstance = $.fn.zTree.getZTreeObj(treeId);
        
        // 50ms 간격으로 로드되지 않은 노드가 남아있는지 폴링
        const pollingTimer = setInterval(() => {
            const pendingNodes = treeInstance.getNodesByFilter(node => !node.zAsync);
            
            // 더 이상 로드할 노드가 없으면 폴링 종료 및 Promise 해결
            if (pendingNodes.length === 0) {
                clearInterval(pollingTimer);
                resolve(treeInstance);
            }
        }, 50);
    });
}

3. 검색 로직 통합

앞서 구현한 대기 메커니즘을 통해 트리가 완전히 준비되면, 안전하게 전체 노드를 대상으로 한 부분 일치 검색을 수행할 수 있습니다.

const targetTreeId = 'dataTree';
const searchKeyword = 'targetValue';

waitForTreeInitialization(targetTreeId).then(readyTree => {
    // 전체 노드에서 키워드를 포함하는 노드 검색
    const matchedNodes = readyTree.getNodesByParamFuzzy('name', searchKeyword, null);
    
    matchedNodes.forEach(node => {
        // 검색된 노드 하이라이트 또는 포커스 이동 로직 처리
        readyTree.selectNode(node);
    });
});

태그: zTree JavaScript jQuery AsyncLoad TreeView

7월 13일 02:46에 게시됨