데이터(JSON)를 트리형(계층형)으로 보여 주기 위해

다음 그림과 같이 들여쓰기를 구현해 본다.

Job2는 Job1의 자식으로 처리하고

그림과 같이 부모인 Job1보다 뒤로 들여쓰기 하여

자식이라는 것을 표현하였다.

트리 구조가 표현되게 되는 것이다.

이러한 표현을 하기 위해서는

가장 먼저 데이터를 구성할 때

부모 / 자식 관계를 제대로 표현해 줘야 하는데

자식 노드(TR)에서 부모 노드(TR)를 지정하는 방식

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

2 가지 방식으로 저장 할 수 있다.


먼저, 자식 노드에서 부모 노드를 지정하는 방법을 알아본다.

개념을 정리해 보면

자식에서 부모를 지정하려면

부모의 고유 식별자(ID)가 있어야 한다.

그래야 특정 노드가 내 부모 임을 표현할 수 있기 때문이다.

따라서, 각 노드(데이터 - data)는

자신을 나타내는 고유 식별 값인 ID와

자신의 부모가 누구 인지 나타내기 위해

부모의 고유 식별 값 ID를 나태내는 값(Parent)이 있어야 한다.


이 값을 가지고

화면 출력을 위해 노드(TR)를 생성할 때

부모가 없으면 노드만 생성하면 된다.

부모가 있으면 최상위 부모(최초 조상-단군)를 찾아서

최상위 부모로부터 몇 대손(depth)인지 파악하고

그 깊이(depth) 만큼 부모로 부터 들여쓰기 해주면 된다.


sample2.html


코드 21 라인에 있는 data 변수의 값을 확인해 보면

앞서의 sample1과 다르게

id와 parent 필드가 추가된 것을 알 수 있다.

앞서 정리한 개념을 처리한 것으로

부모 / 자식 관계를 표현하기 위해 추가하였다.

id 필드의 값은 데이터 내에서 고유한 값이어야 하고,

parent 필드의 값은 나의 부모의 id 값이 저장 된다.


다음은 이렇게 저장한 데이터를 적절하게 화면에 출력하는 것이다.

먼저, 데이터 간의 부모 / 자식 관계를

화면에 표현해야 하는데

데이터 하나가 테이블(TABLE) 태그의 TR로 표현되기 때문에

TR 태그 간의 관계로 구성하게 된다.

다음 단계에서 구현할 접는 기능을 위해서도 필요하다.

즉, TR 태그에 부모 / 자식 관계가 표현되어야 하는데

CSS 클래스명(class속성)으로 처리한다.

HTML 태그의 ID 속성으로 처리하기도 하는데

ID 속성은 이런 저런 데이터를 같이 저장하는 것이 어려워서

대부분 ID 속성 보다는 CSS 클래스명을 이용한다.

TR 태그에도 자기 ID(treegrid9-)와

부모 ID(treegrid9-parent-)가 같이 저장되어야 하기 때문이다.

(이해가 안될 경우 이 글 마지막 그림 참조)


참고: 데이터 값을 식별하는 ID와 HTML 태그의 ID 속성을 혼동할 수 있는데

다른 것이니 잘 구별해서 사용해야 한다.

데이터 값을 식별하는 ID는 고유 값을 가진다는 걸

표현하기 위해 자주 사용하는 변수 이름으로 다른 명칭을 사용해되 된다.


34 라인에 JQuery로 TR을 생성하면서 $("<tr>")

데이터의 id(row.id)와 문자열("treegrid9-")을 합쳐서

클래스를 추가(addClass)하여 TR마다 고유 이름(id)를 부여한다.

데이터의 ID만 사용해도 되지만,

개발한 TreeGrid가 라이브러리 형태로 제공되면

다양한 다른 페이지들과 같이 사용되고

그럴 때 다른 사람이 작성한 클래스명과 같은 경우가 생겨,

문제가 발생할 수 있기 때문에

식별 문자열(treegrid9-)을 추가해서 작성하였다.


참고: data변수에 사용된 id와 parent는 option 변수에 없다.

즉, id와 parent는 화면에 출력되지 않고 숨겨진 필드처럼 사용 된다.


36 라인에서 부모가 있으면(row.parent)

부모의 다음 행에 추가하고(tr.insertAfter)

부모가 없으면 테이블에 추가한다 tr.appendTo(table).

부모를 찾을 때 클래스 명으로 찾는데

JQuery를 이용해서 찾는다.

클래스 명은 점(.)을 이용한다. $(".treegrid9-" + row.parent)


부모 다음에 출력하고 나면

클래스 명에 자신의 부모가 누구라고 표시해야 한다. tr.addClass("treegrid9-parent-" + row.parent);

다만 부모 ID(treegrid9-?)를 그대로 사용하면

명명 규칙이 같아서

어느 것이 자신의 ID이고

어느 것이 부모를 의미하는지 구분할 수 없어

식별 문자열을

자신의 ID는 treegrid9- 으로

부모는 treegrid9-parent- 으로 사용한다.


39 라인의 getDepth 함수에 대한 구체적인 설명은 생략하니 분석해 보길 바란다.

getDepth 함수는

현재 자신이 root로부터 몇 번째 자식인지 계산하는 함수이다 (depth).

원리는 현재 자신(TR)의 클래스 명에 부모가 있는지 확인해 보고

있으면 부모의 ID만 추출하고(parentPattern)

추출된 부모의 ID를 식별문자열(treegrid9-)과 결합해 부모를 찾는다.

다시 그 부모의 클래스 명에서

부모가 있는지 확인해 보고

있으면 부모의 ID만 추출하여 부모를 찾아가면서

부모가 없을 때까지 반복해서 while (parent)

개수를 확인하여 반환한다.


부모의 ID만 추출할때 정규식을 사용하였다.

해당 정규식은 treegrid9-parent-([A-Za-z0-9_-]+) 으로

부모를 나타내기 위해 사용한 식별문자열을 의미한다.


깊이(depth)를 알아야

필드 값을 출력할 때 들여쓰기를 할 수 있다.

깊이가 1 이면(사람으로 치면 단군 왕검의 1 대손이라는 의미)

부모보다 뒤로 몇 글자 들여쓰기 해주면 된다.

공백(&nbsp;)를 사용해도 되지만

여기서는 너비가 16px인 SPAN 태그를 이용해서 구현했다.

깊이가 1 이면 SPAN 태그 하나,

깊이가 2 이면 SPAN 태그 둘 ….

을 생성해서 들여쓰기를 구현하게 된다.


45 라인의 IF문은 if (i===0 && depth>0)

첫 번째 필드(task)만 들여쓰기 하기 위한 것이다.

앞서 43라 인에서 필드의 개수만큼 반복하도록(each) 작성했기 때문에

모든 필드에 대해서 해당 코드가 실행된다.


실행 결과를 DOM 탐색기로 확인하면

다음과 같이 클래스명(class)에

각 행(TR)의 ID와 부모 ID가 표시 되어 있는 것을 볼 수 있다.


정리하면

트리 구조로 보여 주기 위해서는

부모 / 자식 관계 설정을 해야 하고

관계 설정을 위해서는

자신을 식별하는 ID와

부모를 표시하는 Parent가 있어야 한다.

이 두 가지를 데이터에 표현하고

화면에 테이블로 구현해주면 되는 것이다.





+ Recent posts