본문 바로가기

hybrid app/sencha touch

[sencha touch] tabpanel안 cardlayout 고찰

cardlayout에서 레이아웃에 담길 뷰들을 미리 담아 생성하는 경우들이 많다.


Ext.define('xxx.view.Card1',{

extend:'Ext.Panel',

xtype:'card1',

config:{

layout:'card',

items:[

{xtype:'panel1'},

{xtype:'panel2'},

{xtype:'panel3'}

]

}

});


위와 경우 card1라는 이름으로 cardlayout의 패널을 생성후 그 안에 이미 정의한 panel1, panel2, panel3 을 생성해놓았다.


이럴경우 card1패널을 생성하고 card1패널이 보여진다면 panel1이 화면에 보여지게 된다. 그리고 panel1에 show함수를 등록했다면


show함수가 실행된다.



문제가 되는 경우는 다음과 같다.


tab패널을 생성하고  탭바에 뷰들을 담는다. 첫번째 탭바에 방금 위에서 생성한 card1을 담아보겠다.


Ext.define('xxx.view.TabBar',{

extend:'Ext.tab.Panel',

xtype:'tabbar',

config:{

tabBarPosition:'bottom'

items:[

{xtype:'card1'},

{xtype:'card2'},

{xtype:'card3'}

]

}

});


이제 탭바를 화면에 띄우면 card1패널안에있는 panel1이 보여질 것이고 show함수가 실행된다.


card2와 card3도 card1과 같이 cardlayout의 패널이고 뷰가 3개 들어있다고 show 함수가 있다고 하자


그리고 card1, card2, card3 패널에도 show함수를 넣어보자.


그럼 다시 tabpanel을 띄워보자 그러면 card1의 show함수card1안의 panel1 show함수가 실행될 것이고


card2안의 panal1, card3안의 panel1 show 함수가 실행될 것이다.


차이점을 본다면 두번째 세번째 탭의 패널인 card2와 card3의 show함수는 실행되지 않는데 그 안의 panel1의 show 함수들은 실행되었다.


상식적으로 첫번째 탭바의 내용이 보여지므로 두번째 와 세번째는 보이지 않아야 정상일것 같지만 그러지 않았다.


tabpanel이 생성되면서 같이 생성된 card1, card2, card3패널들에 속한 첫번째 패널인 panel1이 보여지면서 show함수가 실행되었다.


이제 두번째 탭바를 선택해 보면 card2의 show 함수는 나오지만 card2안의 panel1의 show함수는 실행되지 않는다.


이미 보여줬기 때문이다.



위와 같다면 다음과 같은 문제를 예상해 볼 수 있다.


card2의 panel1의 화면에서 서버에서 데이터일정 시간단위로 받아 화면에 보여줘야 한다고 하면


처음 실행될때 card1, card2, card3의 panel1의 show함수들이 같이 실행되므로 두번째 탭을 선택하지 않았는데도


서버에서 데이터를 받아오기 시작한다.


그렇다고 card2안 panel1의 show함수가 아니라card2의 show함수에서 데이터를 받아오면


이제 panel1, panel2, panel3를 이동할때 문제가 된다.


뭐 card2와 panel1의 show함수와 hide함수를 사용해서 적절히 만들어준다면 문제가 없을수도 있겠지만 


더 간단하고 메모리도 적게 차지하는 방법을 생각하보면



card레이아웃의 뷰들을 동적으로 생성해서 넣어주고 보여지지 않는 뷰들을 삭제 한다면 위와 같은 문제들은 한번에 해결된다.


그리고 화면에 보여지지 않는 뷰들을 다 destory시킬 것이니 메모리에도 도움이 될 것이다.


동적으로 생성하기 위해 주의할 점이 있다.


보통 컨트롤러 안에서 뷰를 참조할때 다음과 같이 참조한다.


Ext.define('xxx.controller.CardController',{

extend:'Ext.app.Controller',

config:{

refs:{

card1:'card1',

panel1:'panel1',

panel2:'panel2',

panel2:'panel2'

},

contol:{

}

}

});


위와 같다면 뷰를 동적으로 생성시 에러가 발생한다.


아래와 같이 보면 


Ext.define('xxx.controller.CardController',{

extend:'Ext.app.Controller',

config:{

refs:{

card1:'card',

panel1:{

selector:'panel1',

xtype:'pnael1',

autoCreate:true

},

panel2:{

selector:'panel2',

xtype:'pnael2',

autoCreate:true

},

panel3:{

selector:'panel3',

xtype:'pnael3',

autoCreate:true

}

},

control:{

}

}

});


동적으로 생성할 뷰에 selector와 xtype, autoCreate속성을 추가 했다.


위와 같이 해야 동적으로 뷰를 생성하고 cardlayout패널에 넣을 수 있다.


처음에 본 card1에 panel들을 삭제하자


Ext.define('xxx.view.Card1',{

extend:'Ext.Panel',

xtype:'card1',

config:{

items:[

]

}

});


items안을 비워 두었다. 이제 보여주고 싶은 뷰가 있다면 컨트롤러에서 뷰를 생성해서 넣어주면 된다.


컨트롤러에서 뷰를 생성해서 넣어보겠다.


this.getCard1().setActiveItem(this.getPanel1());


이와 같이 하면 panel1을 화면에 보여주게 된다.


panel2를 보여주고 싶다면


this.getCard1().setActiveItem(this.getPanel2()); 다음과 같이 하면 된다.


그리고 화면에 보이지 않는 panel1은 다음과 같이 삭제 시킨다.


this.getPanel1().destory();


이렇게 한다면 tabpanel과 tabpanel안에 속한 cardlayout panel 그리고 화면에 보여지는 패널만 있게 되고 나머지는


메모리에 남아 있지 않는다.


cardlayout패널에 몽땅 다 넣고 만드는 사람들이 있고 뷰들의 실행되는 순서를 헷갈려하는 사람들이 있을까봐 정리해 보았다.


show, hide, initialize, launch 등 실행 흐름이나 순서가 헷갈리면 console.log();