해결책 : callLater 메소드를 사용해 이동시킨 컬럼의 원래 인덱스로 재이동시킨다.
이전에 구미에서 삼성전자 프로젝트를 할 때
과장님이 내게 물었다.
"유대리, 컬럼 시프트 막는 방법 좀 없어?"
내가 말했다.
"안됩니다. 그거... headerShift 이벤트에서 다시 컬럼을 원위치로 스왑시켜 봤는데도 안되구요,
mouseDown 이벤트에서도 안되고 아무튼 안됩니다. 방법 없습니다"
그 때 그렇게 대답할 수 있었던 건
아무래도 무식해서 용감했기 때문인 거 같다.
결론부터 말하면 헤더 시프트를 막는 방법은 있다.
바로 callLater 메소드를 사용하면 된다. (callLater 메소드 관련 링크)
다시 테스트해 보니
컬럼 시프트를 막기 위해서는 굳이 callLater를 쓰지 않아도 된다.
간단히 말해 callLater 메소드는 화면 리프레시와 관련해
이번이 아닌 다음번 리프레시를 기약하는 메소드이다.
이게 무슨 말이냐면,
음...
예를 들어
컬럼을 마우스로 드래그해 다른 컬럼 위치에 드롭하면
컬럼 시프트가 일어나면서
바뀐 컬럼의 모습이 나타나게 된다.
이 때,
드롭하는 시점을 1이라고 하고
바뀐 컬럼이 나타나는 시점을 2라고 하면
1에서 2로 바뀌는 게 하나의 화면 리프레시이다.
그런데 현재 상태가 2라면,
상태 2에서 callLater 메소드를 호출하면
앞으로 있을 상태 3에서 메소드의 반영 결과를 보여주게 된다.
그렇다면, 화면 리프레시는 얼마나 자주 일어날까..
예를 들어, 뭔가를 화면에 add하지 않더라도
화면 리프레시는 계속해서 일어날까?
결론은 "거의 그렇다" 이다. 모든 UIComponent에는 updateDisplayList 메소드가 정의되어 있는데,
callLater 메소드에서 말하는 화면 리프레시는
이 updateDisplayList 메소드가 호출되는 시점을 말한다.
(callLater 메소드는 UIComponent에 최초로 정의되어 있다)
서론은 이쯤으로 하고, 코드를 보도록 하자.
이 예제에서는 컬럼 시프트 핸들러인 shiftHandler 메소드에서
기존 컬럼의 인덱스가 0이면, 즉 옮기려는 컬럼이 첫 번째 컬럼이면,
데이터그리드의 callLater 메소드를 호출해 컬럼을 원 위치로 복귀시키도록 하고 있다.
callLater 메소드는 이처럼 호출할 메소드와 인자를 제한없이 받는 배열 타입의 파라미터를
메소드 시그너처로 정의하고 있다.
reshuffle 메소드가 하는 일은 간단하게 배열의 splice 메소드를 사용해
이동한 첫번째 컬럼을 뽑아내서 다시 원래 위치인 0번째 인덱스에 집어넣은 기능이다.
액션스크립트 원리 : 배열의 splice 메소드는 배열에서 가장 강력한 기능을 하는 메소드이다. 이 메소드는 특정 원소를 한개 또는 여러개 삭제할 수 있을 뿐 아니라, 특정 위치에 원소를 집어넣는 기능 등, 배열 요소 제어와 관련한 모든 기능을 전부 제공하는 배열에 있어서 가장 강력한 메소드이다. splice 메소드를 적절히 활용하면 데이터그리드의 컬럼 순서 제어나 특정 컬럼 삭제, 삽입 등 갖가지 편리한 기능들을 얼마든지 구현할 수 있다.





