본문 바로가기

Flex

ViweStack Change Event - IndexChangeEvent

TabBar / TabNavigator / ButtonBar 등.. ViewStack 과 관련된 컨테이너들을 사용하면서 가장 많이 나오는 질문은 "두번째 탭에 있는 오브젝트를 엑세스 하려고 하니 null 이라고 해요" 이다.

분명이 mxml 에서 다 만들어져 있는데.. 왜 안된다고 하는것인지 모르겠다고 질문이 올라오면.
가장 많이 달리는 답변이. "creationPolicy = "all" 로 해주세요" 이다.

과연 맞을까?

분명 저렇게 하면 에러가 나지 않고 전부 만들어진다.
creationPolicy = "all" 은 생성 정책을 전부 만드는걸로 하겠다는 뜻이다.
탭이 세개가 있으면 탭 세개 안에 들어있는 컴포넌트 들을 처음 로딩시에 전부 만들겠다고 선언하는 것이다. 그럴리야 없겠지만 백개가 있으면 백개를 다 만들게 된다.

공지 사항 탭 / Q&A 탭 / FAQ 탭  이 있다고 했을때 아에 첨부터 세개탭의 데이터를 전부 가져와서 뿌려놓고. 탭을 이동하면 단지 보기만 하면 되도록 만든다면.. 초기 로딩은 좀 느려지겠지만 이후에는 그냥 이동만 하면 되니 괜찮지 않느냐고 이야기 하는 사람도 있을 것이다.

복잡하지 않은 경우 이렇게 처리 하는 것도 뭐 나쁘지는 않을 수 있다.

하지만 뒤쪽 탭을 보지 않는 다면 쓸데 없이 시간과 메모리를 낭비 하게 되는 것 아닌가.

<mx:TabBar id="tabNav" dataProvider="{stack}"/>
<mx:ViewStack id="stack" width="100%" height="100%">
    <mx:Canvas label="Tab 1" backgroundColor="#ff0000">
        <mx:Label id="lbTab1" />
    </mx:Canvas>
    <mx:Canvas label="Tab 2" id="can2" backgroundColor="#00ff00">
        <mx:Label id="lbTab2" />
    </mx:Canvas>
    <mx:Canvas label="Tab 3" backgroundColor="#0000ff">
        <mx:Label id="lbTab3" />
    </mx:Canvas>
</mx:ViewStack>

위 코드에서 뷰스택은 캔버스로 되어있고 캔버스 안에 각각 라벨이 하나씩 있다.
이 라벨값이 1,2,3 이라고 입력되도록 해야 한다.

creationComplete 될때 lbLabel2.text = "2" 하게 되면 해당 객체가 null 이라서 엑세스 할 수 없다는 에러가 발생한다.
ViewStack 의 creationPolicy = "all" 해주면 에러가 깔끔하게 사라진다.

이 방법은 메인에서 탭으로 데이터를 주입해주는 방식이다.

이걸 Event 방식으로 바꾸려면 탭이 선택 되면 그때 자기의 데이터를 가져가도록 바꾸면 된다. 텝이 선택되서 바뀌고 나서 발생하는 이벤트가 이 포스트의 제목인 IndexChangeEvent 이다.
private function init():void
{
	stack.addEventListener(IndexChangedEvent.CHANGE, navIndexChange);
}

private function navIndexChange(e:IndexChangedEvent):void
{
	trace("old : "+e.oldIndex);
	trace("new : "+e.newIndex);
	
	switch(e.newIndex)
	{
		case 0 : lbTab1.text = "텝 1 입니다"; break;
		case 1 : lbTab2.text = "텝 2 입니다"; break;
		case 2 : lbTab3.text = "텝 3 입니다"; break;
	}
}

뷰스텍의 selectedIndex가 변경되게 되면 IndexChangeEvent 가 캐치 된다. e.newIndex / e.oldIndex 값을 통해 이전 인덱스와 바뀐 인덱스 값을 알 수 있게 되므로 해당 페이지에 맞는 내용을 로드 할 수 있게 된다.

간단한 페이지의 경우에는 creationPolicy = "all" 해버리는 쪽이 편하다고 생각할 수 있으나 탭안에 들어가는 내용이 많아 지게 되면 이런 방식으로 바꾸지 않으면 비효율의 극치를 보게 될지도 모른다.

플렉스에서 탭방식으로 동작 하는 것들은 전부 처음 로딩시에 보이는 페이지만을 가져오게 되어있다. 가벼운 RIA 페이지를 위해서는 기본은 지켜서 코딩을 하는 습관을 들이는 쪽이 좋다.

레퍼런스참고
http://livedocs.adobe.com/flex/3/langref/mx/events/IndexChangedEvent.html