사내 위키에 올렸던 글을 다시 정리하여 포스팅하다!
기본 레이아웃 viewport에 각 Region마다 서로다른 패널(panel)을 붙여봅니다.
Basic Concept
각 각의 패널(Panel)에 대하여 알아본다. 기본적인 레이아웃은 이미 앞장에서 설명했던 소스를 이용하여 각각의 Region에 서로 다른 Panel을 붙여본다. 서로다른 패널들이 레이아웃에서 어떻게 붙고(append)되고 자동으로 생성되며(Create) 삭제(remove and destroy)되는지에 대해서 알아본다. 최종적으로 재사용할 컴포넌트모듈을 작성하여 적용하는 방법(Step4)을 소개한다.
각 패널들에 대한 상세한 옵션에 대해서는 장차 설명하기로 하고 여기에서는 기본적인 레이아웃에 패널을 넣는 방식에 대해서 알아본다.
최종소스 :
Step 1. Basic Layout and BoxComponent
우선 이전에 포스팅했던 기본레이아웃 그리기를 준비한다.
[basicLayout.html]
<html>
<head>
<title>Basic Layout</title>
<link rel="stylesheet" type="text/css" href="../../../resources/css/ext-all.css" />
<script type="text/javascript" src="../../../adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../../../ext-all.js"></script>
<script type="text/javascript" src="basicLayout.js"></script>
</head>
<body id="basicLayoutBody"></body>
</html>
[basicLayout.js]
// 좌측 패널 (region : west ) 클래스
WestArea = function() {
WestArea.superclass.constructor.call(this, {
region : 'west',
title : 'WEST',
collapsible : true,
collapsed : false,
width : 300,
minSize : 100,
split : true,
layout : 'fit',
margins : '5 0 5 5',
cmargins : '5 5 5 5',
html : '좌측'
})
};
Ext.extend(WestArea, Ext.Panel, {});
// 우측 패널 (region: east) 클래스
EastArea = function() {
EastArea.superclass.constructor.call(this, {
region : 'east',
title : 'EAST',
collapsible : true,
collapsed : false,
width : 300,
minSize : 100,
split : true,
layout : 'fit',
margins : '5 5 5 0',
cmargins : '5 5 5 5',
html : '우측'
})
};
Ext.extend(EastArea, Ext.Panel, {});
// 중앙 컨텐츠 패널 (region : center) 클래스
CenterArea = function() {
CenterArea.superclass.constructor.call(this, {
region : 'center',
title : 'CENTER',
layout : 'fit',
margins : '5 0 5 0',
html : '<div id="_CONTENTS_AREA_">컨텐츠 영역입니다.</div>'
})
};
Ext.extend(CenterArea, Ext.Panel, {});
// 메인 클래스
BasicLayoutClass = function() {
return {
init : function() {
Ext.QuickTips.init();
this.viewport = new Ext.Viewport( {
layout : 'border',
items : [this.WestPanel = new WestArea(),
this.EastPanel = new EastArea(),
this.CenterPanel = new CenterArea()]
});
this.viewport.doLayout();
this.viewport.syncSize();
}
}
}();
Ext.EventManager.onDocumentReady(BasicLayoutClass.init, BasicLayoutClass, true);
위와 같이 각각의 region마다 별도의 파일로 클래스를 관리한다.
- WestArea.js
- EastArea.js
- CenterArea.js
- basicLayout.js
Step 2. Tab Panel - center region
중앙컨텐츠 패널(center region : CenterArea.js )에 여러개의 TabPanel을 넣어보자
CenterArea = function(viewport) {
this.viewport = viewport;
CenterArea.superclass.constructor.call(this, {
region : 'center',
title : false,
// TabPanel일 경우 Nested된 Panel의 타이틀이 영역을 차지하므로 title은 항상 false가 되어야함.
margins : '5 0 5 0',
deferredRender : false, // CotainerLayout이 로드될때 defer없이 렌더링한다.
tabPosition : 'top', // Tab이 패널의 위쪽에 위치하게 한다. ( 'top'/'bottom'
// 두가지를 지원하며 scrolling TabPanel은 'top'만
// 지원한다.)
activeTab : 0, // 처음 로드(렌더링)될때 첫번째(tab index : 0 ) 탭이 activate되게 한다.
// 기본 Panel을 사용하거나 다른Panel이 Nested 될수 있다.
items : [this.FirstPanel = new Ext.Panel( {
id : 'CENTER_TAB_01',
title : '첫번째 탭',
autoScroll : true,
html : "첫번째"
}), this.SecondPanel = new Ext.Panel( {
id : 'CENTER_TAB_02',
title : '두번째 탭',
autoScroll : true,
html : "두번째"
}), this.ThirdPanel = new Ext.Panel( {
id : 'CENTER_TAB_03',
title : '세번째 탭',
autoScroll : true,
closable : true,
html : "세번째"
})]
})
// activate - 탭이 활성화 될때 일어나는(fire)되는 이벤트
this.SecondPanel.on('activate', function(panel) {
alert(panel.title + '이 활성화 되었습니다.' + panel.getId());
}, this);
// deactivate - 탭이 비활성화될때 일어나는 이벤트
this.SecondPanel.on('deactivate', function(panel) {
alert(panel.title + '이 비활성화 되었습니다.' + panel.getId());
}, this);
// beforedestory - 탭이 닫히기전에 일어나는 이벤트
this.ThirdPanel.on('beforedestroy', function(panel) {
alert(panel.title + '이 닫혔습니다.');
}, this);
};
Ext.extend(CenterArea, Ext.TabPanel, {});
탭패널의 경우 한 화면에 여러개의 패널(Panel)이 필요할 경우 유용하며 연관된 다를 데이타를 사용할때 상당히 유용하다. 기본적인 event는 위에서는 3가지만 열거했지만 위 3가지 만으로도 충분히 다양한 효과를 낼수 있을 것이다. 또한 각 탭 마다 다양한 패널을 추가할수 있으며 기본 ContainerLayout도 추가할수 있으므로 여러가지형태의 레이아웃을 잡을때 상당히 유용하다.
예를 들어 이전장에서 기본레이아웃에 그리드를 추가하는 방법을 배웠는데 첫번째 탭패널에 그리드 레이아웃을 넣어 해당 레이아웃을 테스트 해보기 바란다. 또한 각 탭이 activate될때 그리드의 데이타스토어를 다시 로드할수 있도록 이벤트를 걸어주거나 다른 액션을 취할수 있다.
참고: Ext.TabPanel은 Ext.layout.CardLayout을 사용하므로 deferredRender의 경우 Ext.layout.CardLayout의 deferredRender를 참조한다.
위의 소스중 탭패널이 바로 borderLayout에 속한(region:center)일 경우에는 title 이 나타나지 않는데 기본 Layout에 Nested된 TabPanel일 경우는 기본 Layout의 region에 title을 넣으면 된다. 실제로 작업을 하다보면 위의 방법보다 아래방법을 많이 사용하게 된다. 탭패널안의 탭패널이 들어갈 경우도 발생할수 있으므로 Nested된 패널로 기본 cotainerLayout을 잡은후 넣는 방법이 좋다.
CenterArea = function(viewport) {
this.viewport = viewport;
CenterArea.superclass.constructor.call(this, {
region : 'center',
title : 'CENTER',
layout : 'fit',
margins : '5 0 5 0',
items : [ // Nested된 TabPanel
new Ext.TabPanel( {
deferredRender : false,
tabPosition : 'bottom',
activeTab : 0,
border : false,
enableTabScroll : true,
items : [this.FirstPanel = new Ext.Panel( {
id : 'CENTER_TAB_01',
title : '첫번째 탭',
autoScroll : true,
html : "첫번째"
}), this.SecondPanel = new Ext.Panel( {
id : 'CENTER_TAB_02',
title : '두번째 탭',
autoScroll : true,
html : "두번째"
}), this.ThirdPanel = new Ext.Panel( {
id : 'CENTER_TAB_03',
title : '세번째 탭',
autoScroll : true,
closable : true,
html : "세번째"
})]
})]
})
};
Ext.extend(CenterArea, Ext.Panel, {}); //기본 ContainerLayout
위 소스를 응용하면 탭안의 탭패널, 그안의 탭패널을 넣는 방식으로 계단식 탭패널이 가능하다.
Step 3. Accordian Panel and Tree Panel - west region
좌측패널(WestArea.js, west region)에 Accordian Panel을 붙여본다. 각각의 패널에는 tree Panel 및 여러 Panel이 올수 있다.
WestArea = function(viewport){
this.viewport = viewport;
WestArea.superclass.constructor.call(this,{
region : 'west',
title : 'WEST',
collapsible : true,
collapsed:false,
width : 300,
minSize:100,
split : true,
margins:'5 0 5 5',
cmargins : '5 5 5 5',
// Accordion Layout을 사용
layout:'accordion',
// Accordion Layout의 config option
layoutConfig:{
// 각각의 패널 처음 로드시 collapse먼저 하겠는지 확인
collapseFirst:false,
// 패널 로드시 animated되게 할것인지
animate:true,
// 타이틀을 눌렀을때 collapse할것인지
titleCollapse: true,
// 각각의 패널중 activate될때 맨 처음으로 오게 할것인지
activeOnTop: false,
// 패널의 내용에 상관없이 패널의 높이를 owerContainer의 높이와 맞출것인지 처리
fill:true
},
items: [
this.FirstPanel = new Ext.Panel({
title:'첫번째',
border:false,
html:'<p>트리가 들어갈 곳입니다.</p>'
}),
this.SecondPanel = new Ext.Panel({
title:'두번째',
border:false,
html:'<p>두번째 패널의 내용이 들어갑니다.</p>'
})
]
})
};
Ext.extend(WestArea, Ext.Panel,{ });
accordion Layout으로 바꿨으니 이제 각각의 패널에 알맞은(?) 패널들을 넣어보자. 우선 첫번째 패널에 TreePanel을 넣어보자
WestArea = function(viewport) {
this.viewport = viewport;
WestArea.superclass.constructor.call(this, {
region : 'west',
title : 'WEST',
collapsible : true,
collapsed : false,
width : 300,
minSize : 100,
split : true,
margins : '5 0 5 5',
cmargins : '5 5 5 5',
layout : 'accordion',
layoutConfig : {
collapseFirst : false,
animate : true,
titleCollapse : true,
activeOnTop : false,
fill : true
},
items : [this.FirstPanel = new Ext.tree.TreePanel( {
title : '첫번째',
border : false,
layout : 'fit',
loader : new Ext.tree.TreeLoader( {
dataUrl : 'menu.js',
baseParams : {}
}),
rootVisible : true,
lines : true,
autoScroll : true,
root : new Ext.tree.AsyncTreeNode( {
id : '_MENU_PANEL_',
text : '트리메뉴의 Root',
draggable : false,
expanded : true
})
}), this.SecondPanel = new Ext.Panel( {
title : '두번째',
border : false,
html : '<p>두번째 패널의 내용이 들어갑니다.</p>'
})]
})
};
Ext.extend(WestArea, Ext.Panel, {});
Step 4. Common Modules
이미 Step1,2,3 에서 접해봐서 알겠지만 각각의 패널에는 기본 ContainerLayout만 있으면 어떤 패널이던지 가져다 붙일수 있다는것을 알았을 것이다.
그럼 각각의 공통적으로 사용되는 패널의 경우 공통모듈화 하여 사용자가 정의한 모듈로써 사용하게 된다면 어느 패널에서든지 마음대로 붙였다 떼었다 할수 있을 것이다.
[basicLayout.html]
<html>
<head>
<title>Basic Layout</title>
<link rel="stylesheet" type="text/css" href="../../../resources/css/ext-all.css" />
<script type="text/javascript" src="../../../adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../../../adapter/ext/localXHR.js"></script>
<script type="text/javascript" src="../../../ext-all.js"></script>
<script type="text/javascript" src="Modules.js"></script>
<script type="text/javascript" src="WestArea.js"></script>
<script type="text/javascript" src="EaseArea.js"></script>
<script type="text/javascript" src="CenterArea.js"></script>
<script type="text/javascript" src="basicLayout.js"></script>
</head>
<body id="basicLayoutBody"></body>
</html>
[Modules.js]
Ext.namespace("Ext.techbug");
// 공통으로 사용되는 트리메뉴
Ext.techbug.TreeMenu = function(config) {
Ext.apply(this, config);
Ext.techbug.TreeMenu.superclass.constructor.call(this, {
loader : new Ext.tree.TreeLoader( {
dataUrl : 'menu.js',
baseParams : {}
}),
rootVisible : true,
lines : true,
autoScroll : true,
root : new Ext.tree.AsyncTreeNode( {
id : '_MENU_PANEL_',
text : '트리메뉴의 Root',
draggable : false,
expanded : true
})
})
};
Ext.extend(Ext.techbug.TreeMenu, Ext.tree.TreePanel, {});
[WestArea.js]
WestArea = function(viewport) {
this.viewport = viewport;
WestArea.superclass.constructor.call(this, {
region : 'west',
title : 'WEST',
collapsible : true,
collapsed : false,
width : 300,
minSize : 100,
split : true,
margins : '5 0 5 5',
cmargins : '5 5 5 5',
layout : 'accordion',
layoutConfig : {
collapseFirst : false,
animate : true,
titleCollapse : true,
activeOnTop : false,
fill : true
},
items : [
// 공통모듈로 사용하는 트리메뉴로 변경
this.FirstPanel = new Ext.techbug.TreeMenu( {
title : '첫번째',
border : false,
layout : 'fit'
}), this.SecondPanel = new Ext.Panel( {
title : '두번째',
border : false,
html : '<p>두번째 패널의 내용이 들어갑니다.</p>'
})]
})
};
Ext.extend(WestArea, Ext.Panel, {});