부모 노드가 자식 리스트를 보유하는 방식은

데이터에 내 자식 리스트(배열)을 표시하면 된다.

앞서 구현한 자식 노드에서 부모 노드를 지정하는 방식은

부모가 하나이기 때문에 parent 변수 하나만 추가하면 됐지만

한 부모의 자식은 여럿이 될 수 있기 때문에

배열(children)을 사용해야 한다.

그리고, 자식의 자식의 자식의 ... 로 작성될 수 있기 때문에

배열의 배열의 배열...

과 같이 무한하게 표시될 수 있다.

이렇게 무한하게 표현되는 데이터를 처리하기 위해서는

데이터가 있는 만큼 무한하게

반복해서 처리할 수 있는 재귀 함수가 필요하다.

데이터(행)를 처리하고

해당 데이터에 자식이 있으면

다시 데이터를 처리하고

해당 데이터에 자식이 있으면 ....

이렇게 반복되는 것을 하나만 함수로 작성하고

데이터가 없을 때까지 반복해서 호출하는 것을 재귀함수 라고 한다.



sample2_1.html


먼저, 20 라인의 데이터를 보면

앞서 구현한 자식 노드에서 부모 노드를 지정하는 방식과 비슷하게

자신을 나타내는 ID가 추가되었다.

다만, 부모 대신에 자식들(children)이 배열로 구현되어 있다.

부모는 하나지만

자식은 여러 명일 수 있기 때문에 복수형으로 사용한다.

자식 필드로 children이 선언되고

부모와 동일한 구조로 데이터가 저장된다.

여기서는 처리하지 않았지만

자식의 자식일 경우

Children을 계속 넣어주면 된다.


앞서의 방식보다 코드가 깔끔해 보이는데

재귀 호출을 사용하였다.

재귀 호출, 재귀 함수라고도 하는데

자신이 자신을 부르는 것을 의미한다.

자식이 어느 정도(몇 대손)까지 있을 지 모르기 때문에

자식에 대한 처리를 위해 재귀 호출을 사용했다.


재귀 함수인 setData는

파라미터로 데이터와 부모 태그, 깊이(몇 대손)를 주게 된다.

데이터는 자식 리스트(children)를 의미하고,

부모 태그는 부모 TR을 의미하는 데

첫 데이터(단군)은 테이블(table) 태그이다.

깊이는 처음에 0 일 것이고

재귀호출 할 때 마다 1 씩 더해 준다.


주어진 데이터의 개수 만큼 반복해서 $.each( data, function( index, row)

TR을 생성하고

CSS 클래스 명으로 이름을 부여한다.

다만, 위치는

부모가 없으면 테이블에 추가하고(appendTo)

부모가 있으면 부모 다음에 넣어준다 (insertAfter).

다만 조금 더 정확하게 구현하려면 부모 다음이 아니고

해당 부모의 마지막 자식 다음이 되어야 한다.

구현 방법이 복잡해서 여기서는 부모 다음에 추가했다.

부모가 있는지 없는지는

파라미터로 넘어온 부모의 태그 타입(nodeName)이

테이블이면 부모가 없는 것으로 처리했다.


들여쓰기 하는 방식은

자식 노드에서 부모 노드를 지정하는 방법과 같이

깊이의 개수만큼 SPAN 태그를 생성해 준다.


마지막으로 자식이 있으면 if (row.children)

다시 자신(setData)을 호출하고

파라미터로 자식 리스트를 넣어주면 된다.


자식 노드에서 부모 노드를 지정하는 방식(sample2.html)과

부모 노드가 자식 리스트를 보유하는 방식(sample2_1.html)을 구현하였다.

일반적으로 대부분의 라이브러리들이 (TreeGrid jQuery, EasyTree)

부모 노드가 자식 리스트를 보유하는 방식을 사용하고 있다.


하지만, 개인적으로

자식 노드에서 부모 노드를 지정하는 방식이 더 좋다고 생각한다.

데이터 베이스에 데이터가 저장되는 방식이

자식 노드에서 부모 노드를 지정하는 방식과 같기 때문이다.

(본 블로그의 무한 댓글 참조)

즉, 데이터 베이스에 ID와 Parent 필드로 저장하고 있다.

부모 노드가 자식 리스트를 보유하는 방식을 사용하게 되면

ID와 Parent 필드로 구성된 데이터를 정리해서

자식 리스트를 작성해야 하기 때문이다.

즉, Java나 PHP등의 서버 언어에서의 처리가 있어야 한다.


따라서 JS 코드만 보면

자식 노드에서 부모 노드를 지정하는 방식이 더 복잡하지만

데이터 베이스의 데이터를 그대로 사용할 수 있기 때문에

이후의 기능 개선도

자식 노드에서 부모 노드를 지정하는 방식으로 구현할 예정이다.



+ Recent posts