Creative Wrong Answer

리스트의 아이템을 선택해서 위치를 위로 올려주는 프로그램이다.

 

private var arrData:Array;
private var idx:int;
			
private function init():void
{
	arrData = [];
	arrData.push({label:"데이터1", data:"data1"});
	arrData.push({label:"데이터2", data:"data2"});
	arrData.push({label:"데이터3", data:"data3"});
	list.dataProvider = arrData;
}
			
private function posUp():void
{
	if(list.selectedItem && list.selectedIndex != 0)
	{
		idx= list.selectedIndex;
		var tmpArr:Array = arrData.splice(idx,1);
		arrData.splice(idx -1,0,tmpArr[0]);
		list.dataProvider = arrData;
		list.selectedIndex = idx-1;
		trace(list.selectedIndex);
	}
}

 

List 컴포넌트의 아이디는 list 이고 버튼을 클릭하면 posUp()함수가 호출된다.

 

dataProvider 로 쓰이는 arrData 배열을 편집해서 선택한것을 한단계 위로 올리고 그것을 다시 List의 dataProvider로 세팅해준다.

 

이후에 list의 selectedIndex를 idx-1 값으로 즉 이전 선택 인덱스-1의 값으로 만들어준다. 위 코드로 만들게 되면 한번은 실행이 정상적으로 되는 것처럼 보인다.

세번째 데이터를 선택하고 버튼을 눌러서 posUp()을 호출하면 화면상에서 보이는 위치와 선택된 상태가 바뀐다. 즉, selectedIndex가 2 에서 1로 바뀌는 것처럼 보인다.

하지만 아랫줄의 trace 값에서 list.selectedIndex를 찍어보면 1이 아니고 2로 나온다..

 

이전의 selectedIndex가 그대로 호출되는 것이다.

 

 한번더 버튼을 누르면 2번이 1번으로 올라가지 않고 2,3 번이 위치를 바꾸는 기현상이 일어난다.

 

 

이 코드를 정상 작동하게 만들기 위해서는 아래처럼 수정한다.

import mx.events.FlexEvent;
			
private var arrData:Array;
private var idx:int;
			
private function init():void
{
	arrData = [];
	arrData.push({label:"데이터1", data:"data1"});
	arrData.push({label:"데이터2", data:"data2"});
	arrData.push({label:"데이터3", data:"data3"});
	list.dataProvider = arrData;
}
			
private function posUp():void
{
	if(list.selectedItem && list.selectedIndex != 0)
	{
		idx= list.selectedIndex;
		var tmpArr:Array = arrData.splice(idx,1);
		arrData.splice(idx -1,0,tmpArr[0]);
		list.dataProvider = arrData;
		list.addEventListener(FlexEvent.UPDATE_COMPLETE, handler);
	}
}
			
private function handler(e:FlexEvent):void
{
	list.selectedIndex = idx-1;
}

 

selectedIndex를 변경시켜주는 시점을 결정하기 위해서 list가 업데이트가 끝났다는 이벤트를 받아서 완료되면 인덱스를 수정해주는 것이다.

 

 

이처럼 Flex나 Flash는 몇몇 method를 제외하고는 비동기로 동작하기 때문에 데이터의 수정이나 삭제 입력시에 해당 행위가 끝났는지를 파악해서 이후의 작업을 하는 것이 중요한 경우가 있다.

list.dataProvider = arrData;
list.selectedIndex = 1;

이렇게 실행시켰을때 코드 한줄 차이로 바로 아래에 있지만 list.selectedIndex=1이 호출되는 시점에서 list.dataProvider가 null 일수도 있다.

이런 문제는 발생하는 경우도 있고 어떤때는 정상적으로 실행되는것처럼 보이기도 하기 때문에 인지하지 못하고 있으면 어디에서 문제가 생겼는지 찾지 못해서 머리를 쥐어뜯게 되는 경우가 생길수도 있다.

 

이벤트를 이해하고 정상적으로 처리될 수 밖에 없도록 프로그래밍을 하는것이 최고의 방법일 것이다.

 

 

List 상하로 변경하기 2 - 스크롤포지션 세팅

신고

Comment +3

  • 이 포스트 덕에 많은 도움이 되었습니다.
    감사합니다.

  • selectedIndex를 변경하는건 바로 변경이 되지를 않네요. selectedItem을 이용하여 array에서 지정된 index에 해당하는 아이템을 찾은후에

    list.selectedItem = arrData[idx-1];

    위와 같이 하면 이벤트 처리 없이 선택할 수도 있겠네요.

    • 도움이 됐다니 다행입니다.

      item이나 index나 사실은 똑같은 놈을 가리키고 있으니 어느쪽을 사용해도 별 문제는 없다고 생각합니다.

      다만 이벤트를 사용하는 것이 아무래도 런타임에 발생하는 오류의 빈도를 줄일 수 있다라는 것이 포스트의 요지입니다.

      관리만 잘된다면 이벤트가 편하긴 하죠. 직관적으로 코드 읽기는 역시 직접 세팅이 좋지만요 ㅎㅎ