본문 바로가기
Web Front 개발공부/Web Front 기타

웹스퀘어 그리드 부모 자식 1:N 조회 구성

by 슬기로운 동네 형 2023. 5. 5.
반응형

웹스퀘어 그리드 부모 자식 1:N 조회 구성

상하

 부서정보가 조회되고 해당 부서에 마우스를 클릭하면 하단 사원정보 그리드에 해당 부서의 속한 사원리스트가 나오는 화면을 구성해 본다.

부서정보 그리드에 1001 이면 1001부서에 속한 사원정보 조회

두 가지 방법이 존재한다.

1. 부서정보의 그리드를 클릭할 때마다 서버와 통신을 해서 사원정보를 조회하는 방법

2. 최초에 조회를 할 때, 부서정보 전체와 사원정보 전체를 모두 서버로부터 갖고 와서 사원정보를 필터 형태로 그리드에서 나타내게 하는 방법.

 

 두 가지 방법대로 장단점이 존재하는데.

 2번 방법의 경우 데이터가 많다면 문제가 된다. 데이터가 많다면 초기 로딩이 문제가 될 텐데 막상 로딩 후에는 빠르게 필터링이 된다.

 1번의 경우 단점은 역시 서버와 통신이 너무 잦다는 것. 하지만 최신 정보를 가져올 수 있다. 처음에는 빠르지만 역시나 데이터 량이 많으면 통신에 부담이 도어 조회가 느릴 수 있다. 

 

데이터 량이 고민되어야 하고, 트랜잭션 생성이나 변경이 수시로 일어난 다면 1번 방법이 적당할 듯하다. 

 

 아무튼...

 문제가 있는데 내가 웹스퀘어 API를 아무리 뒤져봐도 데이터리스트 속성 중에 필터를 걸어서 그리드와 동기화되는 기능을 못 찾은 것이다. 웹스퀘어를 만든 회사에서 제공하는 예제는 서버를 다녀오는 것 밖에 없고...

  우선은 연습도 할 겸 LinkedDataList와 사원정보의 데이터리스트를 두 개 만들어서 꼼수를 부려 봤다.

 

조회 시, 부서정보와 사원정보를 모두 읽어 들여서 각각의 데이터리스트에 담는다.

이때 사원정보용 오리지널 데이터리스트와 링크드 데이터리스트를 연결해 놓는다. 그리고 부서정보 그리드의 onrowindexchange 이벤트가 일어날 때마다 선택된 부서번호를 갖고 사원 링크드데이터리스트에 필터를 건다. 필터가 되면 그 자료를 사원정보 그리드와 연결된 조회전용 두 번째 사원데이터리스트에 넣어서 조회 효과를 구현한다.

 

전체 소스는 아래와 같다

	scwin.onpageload = function() {

	};

	scwin.onpageunload = function() {

	};

	//onrowindexchange 메인그리드 커서가 옮겨질때마다 실행 된다.
	scwin.mainGrid_onrowindexchange = function(row, oldRow) {
		//해당 컬럼 인덱스의 전체 row의 정보를 배열로 리턴
		//console.log(dlt_emp.getFilteredColData(0));    //epm의 부서번호 배열

		//1.원본 직원정보 데이터리스트를 서버로부터 갖고온다.
		//2.원본에 데이터링크드 리스트를 연결해놓고 필터링을 건다.
		//3. 필터링 건 놈을 동일한 조회전용 직원정보데이터리스트에 다시 넣어서 조회된 것처럼 필터링 효과를 준다. 이것은 그리드와 연결 됨
		//scwin.deptNo = ;

		scwin.vDeptNo = dlt_dept.getCellAllData(row, 'deptNo');

		dlt_empListB.removeAll();
		ldt_linkedEmpList.setCondition("filter", "deptNo==" + scwin.vDeptNo);
		for (var i = 0; i < ldt_linkedEmpList.getRowCount(); i++) {
			dlt_empListB.setRowData(i, ldt_linkedEmpList.getRowData(i));
		}
	};

	scwin.serverQuery = function(e) {

	}

	scwin.btnSerch_onclick = function(e) {
		scwin.loadData(); // 부서정보 데이터 셋팅
		scwin.loadEmpData();
	};

	//데이터 셋팅
	scwin.loadData = function() {
		dlt_dept.removeAll(); //초기화

		dlt_dept.insertRow(0);
		dlt_dept.setCellData(0, 'deptNo', '1001');
		dlt_dept.setCellData(0, 'deptNm', '재무');
		dlt_dept.setCellData(0, 'location', '본관2층 101호');

		dlt_dept.insertRow(1);
		dlt_dept.setCellData(1, 'deptNo', '1002');
		dlt_dept.setCellData(1, 'deptNm', '경영기획팀');
		dlt_dept.setCellData(1, 'location', '본관2층 102호');

		dlt_dept.insertRow(2);
		dlt_dept.setCellData(2, 'deptNo', '1003');
		dlt_dept.setCellData(2, 'deptNm', '금융팀');
		dlt_dept.setCellData(2, 'location', '본관2층 103호');

		dlt_dept.insertRow(3);
		dlt_dept.setCellData(3, 'deptNo', '1004');
		dlt_dept.setCellData(3, 'deptNm', '인사팀');
		dlt_dept.setCellData(3, 'location', '본관2층 104호');
	}

	//인원구성 데이터 셋팅
	scwin.loadEmpData = function() {
		dlt_emp.removeAll(); //초기화
		for (var i = 0; i < 7; i++) {
			dlt_emp.insertRow(i);
			dlt_emp.setCellData(i, 'empNo', '93001');
			if (i == 0) {
				dlt_emp.setCellData(i, 'deptNo', '1001');
				dlt_emp.setCellData(i, 'empNm', '강하늘');
			} else if (i == 1) {
				dlt_emp.setCellData(i, 'deptNo', '1001');
				dlt_emp.setCellData(i, 'empNm', '조만배');
			} else if (i == 2) {
				dlt_emp.setCellData(i, 'deptNo', '1001');
				dlt_emp.setCellData(i, 'empNm', '정준호');
			} else if (i == 3) {
				dlt_emp.setCellData(i, 'deptNo', '1001');
				dlt_emp.setCellData(i, 'empNm', '이병헌');
			} else if (i == 4) {
				dlt_emp.setCellData(i, 'deptNo', '1002');
				dlt_emp.setCellData(i, 'empNm', '유준상');
			} else if (i == 5) {
				dlt_emp.setCellData(i, 'deptNo', '1002');
				dlt_emp.setCellData(i, 'empNm', '이만기');
			} else if (i == 6) {
				dlt_emp.setCellData(i, 'deptNo', '1003');
				dlt_emp.setCellData(i, 'empNm', '서태지');
			}
		}

		//데이터 리스트 복사
		/*
		for(var i=0;  i <  dlt_emp.getRowCount();i++){
		  dlt_empListB.setRowData(i, dlt_emp.getRowData(i));
		}
		 */

	}

 

링크드 데이터 리스트가 그리드에 바인딩이 될 줄 알았는데 안된다. 헐... 역시나 유튜브 동영상에서는 키, 값 형태의 selectBox, 멀티 셀렉트박스에 사용한다고 설명이 되어 있던데... 그리드와는 직접 연결기능이 있다면 좋았을 거 같은데... 아쉽다.

 단순히 오리지널 데이터리스트와 바인딩 된 그리드가 있고 해당 오리지날 데이터리스트를 필터를 걸 수 있다면 좋을 텐데... 그리드에서는 Ui 칼럼에서 기능이 구현이 되던데 코딩으로는 안되나 보다. 아니면 내가 아직 못 찾은 것일 수도...

 한번 다시 찾아봐야겠다.

 

 

앗....이런..

dlt_empListB.setColumnFilter(filterOptions)

이런 기능이 있었네... 에궁.


3. setColumnFilter

setColumnFilter를 적용

	//부서정보 그리드 Row 인덱스 변경시마다 이벤트
	scwin.mainGrid_onrowindexchange = function(row, oldRow) {
	    
	   //필터링 해제
	   dlt_emp.clearFilter();
	   
	   scwin.vDeptNo = dlt_dept.getCellAllData(row, 'deptNo');
	   dlt_emp.setColumnFilter( {type:'row', colIndex:'deptNo', key:scwin.vDeptNo, condition:'and'});
	   alert('필터 된 부서 '+ scwin.vDeptNo);
	};

 부서정보 그리드의 마우스 커서가 Row 변경이 일어 날때 마다 이벤트에

 필터링 해제를 꼭 달아야 초기화가 된다. 초기화이긴 한데 데이터리스트의 데이터가 없어지는 것은 아니고 단순 필터링해제다.

API를 보니

 "위의 방법은 효율이 좋지 않으므로 아래와 같이 사용자정의 필터 또는 정규표현식을 이용하여 한번에 적용할 것을 권장."

라고 한다.

다른 프레임워크의 그리드 Row 필터링과 비슷하다.


변경된 방식 최종 필터 기능

	//부서정보 그리드 Row 인덱스 변경시마다 이벤트
	scwin.mainGrid_onrowindexchange = function(row, oldRow) {
	    
	   //필터링 해제
	   dlt_emp.clearFilter();
	   
	   scwin.vDeptNo = dlt_dept.getCellAllData(row, 'deptNo');
	   
	   //효율이 좋지 않은 방식
	   //dlt_emp.setColumnFilter( {type:'row', colIndex:'deptNo', key:scwin.vDeptNo, condition:'and'});
	   
	   //---------------------------------------------------------------------------
	   //추천 하는 방식
	   //---------------------------------------------------------------------------
            
            //1. 사용자 정의 함수를 만든다.
            var fn_tmpDeptFilter = function(cellData, tmpParam, rowIdx){
                if(cellData.indexOf(scwin.vDeptNo) > -1){
                    return true;
                }
                return false;   //return이 true인 경우 적용하고 false인 경우 skip한다.
            }   

        // (예제) deptNo 컬럼의 부서번호가 현재 부서정보번호 만...
        //2. type을 func로 하고, key를 사용자 정의 함수를 적용
            dlt_emp.setColumnFilter( 
                {type:'func', colIndex:'deptNo', key:fn_tmpDeptFilter, condition:'and'}
            );
	};

 

반응형

댓글