AJAX & UI 강의자료
본 강의자료는 복제, 배포가 불가능합니다. by techbug
Internet Explorer 8
Reference Books





![]() |

'강좌 및 번역' 카테고리의 다른 글
HTML5 (10) | 2010.03.02 |
---|---|
프로젝트 관리자가 알아야할 97가지 사실 (1) | 2009.12.08 |
|
![]() |
HTML5 (10) | 2010.03.02 |
---|---|
프로젝트 관리자가 알아야할 97가지 사실 (1) | 2009.12.08 |
window.onload = initialize;
function initialize() {
// initialize the DHTML History
// framework
dhtmlHistory.initialize();
window.onload = initialize;
function initialize() {
// DHTML 히스토리 프레임워크를 초기화한다
dhtmlHistory.initialize();
// HTML 히스토리 변경 이벤트를 구독한다
dhtmlHistory.addListener(historyChange);
/** 히스토리 변경 이벤트를 받기 위한 콜백 */
function historyChange(newLocation,
historyData) {
debug("A history change has occurred: "
+ "newLocation="+newLocation
+ ", historyData="+historyData,
true);
}
window.onload = initialize;
function initialize() {
// initialize the DHTML History
// framework
dhtmlHistory.initialize();
// subscribe to DHTML history change
// events
dhtmlHistory.addListener(historyChange);
// if this is the first time we have
// loaded the page...
if (dhtmlHistory.isFirstLoad()) {
debug("Adding values to browser "
+ "history", false);
// start adding history
dhtmlHistory.add("helloworld",
"Hello World Data");
dhtmlHistory.add("foobar", 33);
dhtmlHistory.add("boobah", true);
var complexObject = new Object();
complexObject.value1 =
"This is the first value";
complexObject.value2 =
"This is the second data";
complexObject.value3 = new Array();
complexObject.value3[0] = "array 1";
complexObject.value3[1] = "array 2";
dhtmlHistory.add("complexObject",
complexObject);
http://codinginparadise.org/my_ajax_app#helloworld
window.onload = initialize;
function initialize() {
// initialize the DHTML History
// framework
dhtmlHistory.initialize();
// subscribe to DHTML history change
// events
dhtmlHistory.addListener(historyChange);
// if this is the first time we have
// loaded the page...
if (dhtmlHistory.isFirstLoad()) {
debug("Adding values to browser "
+ "history", false);
// start adding history
dhtmlHistory.add("helloworld",
"Hello World Data");
dhtmlHistory.add("foobar", 33);
dhtmlHistory.add("boobah", true);
var complexObject = new Object();
complexObject.value1 =
"This is the first value";
complexObject.value2 =
"This is the second data";
complexObject.value3 = new Array();
complexObject.value3[0] = "array 1";
complexObject.value3[1] = "array 2";
dhtmlHistory.add("complexObject",
complexObject);
window.onload = initialize;
function initialize() {
// initialize the DHTML History
// framework
dhtmlHistory.initialize();
// subscribe to DHTML history change
// events
dhtmlHistory.addListener(historyChange);
// if this is the first time we have
// loaded the page...
if (dhtmlHistory.isFirstLoad()) {
debug("Adding values to browser "
+ "history", false);
// start adding history
dhtmlHistory.add("helloworld",
"Hello World Data");
dhtmlHistory.add("foobar", 33);
dhtmlHistory.add("boobah", true);
var complexObject = new Object();
complexObject.value1 =
"This is the first value";
complexObject.value2 =
"This is the second data";
complexObject.value3 = new Array();
complexObject.value3[0] = "array 1";
complexObject.value3[1] = "array 2";
dhtmlHistory.add("complexObject",
complexObject);
// cache some values in the history
// storage
debug("Storing key 'fakeXML' into "
+ "history storage", false);
var fakeXML =
'<?xml version="1.0" '
+ 'encoding="ISO-8859-1"?>'
+ '<foobar>'
+ '<foo-entry/>'
+ '</foobar>';
historyStorage.put("fakeXML", fakeXML);
}
window.onload = initialize;
function initialize() {
// initialize the DHTML History
// framework
dhtmlHistory.initialize();
// subscribe to DHTML history change
// events
dhtmlHistory.addListener(historyChange);
// if this is the first time we have
// loaded the page...
if (dhtmlHistory.isFirstLoad()) {
debug("Adding values to browser "
+ "history", false);
// start adding history
dhtmlHistory.add("helloworld",
"Hello World Data");
dhtmlHistory.add("foobar", 33);
dhtmlHistory.add("boobah", true);
var complexObject = new Object();
complexObject.value1 =
"This is the first value";
complexObject.value2 =
"This is the second data";
complexObject.value3 = new Array();
complexObject.value3[0] = "array 1";
complexObject.value3[1] = "array 2";
dhtmlHistory.add("complexObject",
complexObject);
// cache some values in the history
// storage
debug("Storing key 'fakeXML' into "
+ "history storage", false);
var fakeXML =
'<?xml version="1.0" '
+ 'encoding="ISO-8859-1"?>'
+ '<foobar>'
+ '<foo-entry/>'
+ '</foobar>';
historyStorage.put("fakeXML", fakeXML);
}
// retrieve our values from the history
// storage
var savedXML =
historyStorage.get("fakeXML");
savedXML = prettyPrintXml(savedXML);
var hasKey =
historyStorage.hasKey("fakeXML");
var message =
"historyStorage.hasKey('fakeXML')="
+ hasKey + "<br>"
+ "historyStorage.get('fakeXML')=<br>"
+ savedXML;
debug(message, false);
}
/** 페이지가 로딩을 끝낸 후에 초기화를 수행하는 함수 */
function initialize() {
// DHTML 히스토리 프레임워크를 초기화한다
dhtmlHistory.initialize();
// DHTML 히스토리 리스너에 등록한다
dhtmlHistory.addListener(handleHistoryChange);
// 주소록을 가져올 수 없으면 직접 추가한 주소록을
// 히스토리 저장소에서 캐싱한다.
if (window.addressBook == undefined) {
// 주소록을 전역 객체로 저장한다
// 실제 응용프로그램에서는 백그라운드에서 서버로부터
// 주소록을 가져와야한다
window.addressBook =
["Brad Neuberg 'bkn3@columbia.edu'",
"John Doe 'johndoe@example.com'",
"Deanna Neuberg 'mom@mom.com'"];
// 주소록이 있으면 이를 캐시에 보관한다
// 사용자가 페이지를 떠난 후에 뒤로 이동으로 돌아온 경우에도 사용한다
historyStorage.put("addressBook",
addressBook);
}
else {
// 히스토리 저장소에서 캐시된 주소록을 가져온다
window.addressBook =
historyStorage.get("addressBook");
}
/** 히스토리 변경 이벤트를 처리한다 */
function handleHistoryChange(newLocation,
historyData) {
// 위치가 없으면 수신함의 기본 위치를 보여준다
if (newLocation == "") {
newLocation = "section:inbox";
}
// 위치 변화가 있으면 표시할 섹션을 추출한다.
// newLocation은 "section:"으로 시작한다
newLocation =
newLocation.replace(/section\:/, "");
// DHTML 히스토리 변경에 따라 브라우저를 업데이트한다
displayLocation(newLocation, historyData);
}
/** 오른쪽 컨텐트 영역에 주어진 위치를 표시한다*/
function displayLocation(newLocation,
sectionData) {
// 선택한 메뉴 항목을 가져온다
var selectedElement =
document.getElementById(newLocation);
// 이전에 선택된 메뉴 항목을 제거한다
var menu = document.getElementById("menu");
for (var i = 0; i < menu.childNodes.length;
i++) {
var currentElement = menu.childNodes[i];
// DOM 요소 노드인지 확인한다
if (currentElement.nodeType == 1) {
//모든 클래스 이름을 제거한다
currentElement.className = "";
}
}
// UI에서 다르게 나타나는 새로 선택된 메뉴 항목
selectedElement.className = "selected";
// 화면 오른쪽에 새로운 섹션을 표시한다.
// sectionData에 따라 섹션을 결정한다
// 앞서 캐시된 로컬 주소 데이터를 사용해서 주소록을 보여준다
if (newLocation == "addressbook") {
// 주소록을 보여준다
sectionData = "<p>Your addressbook:</p>";
sectionData += "<ul>";
// 주소록이 아직 없다면 캐시에서 주소록을 가져온다
if (window.addressBook == undefined) {
window.addressBook =
historyStorage.get("addressBook");
}
// 주소록을 표시한다
for (var i = 0;
i < window.addressBook.length;
i++) {
sectionData += "<li>"
+ window.addressBook[i]
+ "</li>";
}
sectionData += "</ul>";
}
// sectionData가 없다면 원격으로 가져온다. 이 예제에서는 주소록을 제외한
// 모든 데이터는 가짜를 이용하고 있다
if (sectionData == null) {
// 실제 응용프로그램에서는 섹션의 내용을 원격으로 가져와야한다
sectionData = "<p>This is section: "
+ selectedElement.innerHTML + "</p>";
}
// 제목과 내용을 업데이트한다
var contentTitle =
document.getElementById("content-title");
var contentValue =
document.getElementById("content-value");
contentTitle.innerHTML =
selectedElement.innerHTML;
contentValue.innerHTML = sectionData;
}
Ajax Framework 분석 (0) | 2009.05.04 |
---|---|
CSSHttpRequest (0) | 2008.11.12 |
HTTP Header에 대하여 (0) | 2008.11.08 |
100라인 Ajax Wrapper (0) | 2008.04.19 |
어떤 AJAX Framework를 선택할 것인가. (0) | 2008.03.14 |
echo Ext::onReady( Javascript::stm(ExtQuickTips::init()), Javascript::assign("data",Javascript::valueToJavascript($myData)), //Javascript::valueToJavascript($myData), $store->getJavascript(false, "ds"), $italicRenderer, $changeRenderer, $pctChangeRenderer, $colModel->getJavascript(false, "colModel"), $gridForm->getJavascript(false, "gridForm") ); $gridForm = new ExtFormPanel("company-form"); $gridForm->Frame = true; $gridForm->LabelAlign = EXT_FORM_LABEL_ALIGN_LEFT; $gridForm->Title = "Company Data"; $gridForm->BodyStyle = "padding: 5px;"; $gridForm->Width = 750; $gridForm->Layout = EXT_CONTAINER_LAYOUTS_COLUMN;
Ext JS Ext.ux.YoutubePlayer (0) | 2008.03.29 |
---|---|
Extjs를 이용한 간단한 form submit (0) | 2008.03.14 |
Extjs Grouping Header Grid Plugins (13) | 2008.03.06 |
Extjs 크로스 도메인 관련 (0) | 2008.02.28 |
Extjs 한국어로 나타내기 (locale설정) (9) | 2008.02.27 |
function isAjax() {
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) &&
$_SERVER ['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
}
Extjs를 이용한 ExtPHP, PHP-Ext 프로젝트 오픈 (0) | 2008.03.07 |
---|---|
Extjs Grouping Header Grid Plugins (13) | 2008.03.06 |
Extjs 한국어로 나타내기 (locale설정) (9) | 2008.02.27 |
ExtJS을 이용한 RestFul한 통신하기 (2) | 2008.02.26 |
GWT Ext 2.0 이 릴리즈됐다. (0) | 2008.02.26 |
Extjs 한국어로 나타내기 (locale설정) (9) | 2008.02.27 |
---|---|
ExtJS을 이용한 RestFul한 통신하기 (2) | 2008.02.26 |
ExtJS를 지원하는 IDE 개발이 시작되다. (0) | 2008.02.26 |
ExtTLD : XML을 이용한 Extjs 컴포넌트 생성 (0) | 2008.02.26 |
Extjs를 이용한 PHP 플러그인 Simplicity (0) | 2008.02.26 |
GWT Ext 2.0 이 릴리즈됐다. (0) | 2008.02.26 |
---|---|
ExtJS를 지원하는 IDE 개발이 시작되다. (0) | 2008.02.26 |
Extjs를 이용한 PHP 플러그인 Simplicity (0) | 2008.02.26 |
Extjs v2.02 릴리즈 (0) | 2008.02.26 |
Extjs 기본레이아웃에 grid panel 붙이기 (0) | 2008.02.25 |
들어가며
본 포스팅은 사내(넥스트리소프트) 솔루션 개발시 가이드작성했던 문서를 다시 정리하여 올린것입니다.
기본개념
기본적인 Grid 사용법및 DataStore 및 RowSelectionModel에 대해 알아본다.
GridPanel을 이용하여 데이타스토어에 저장된 데이타를 가져오는 법과 기본적인 그리드 렌더링 방법, 각각의 Row에 대한 Model에서 Data를 축출하는 법에 대해서 기술한다.
아래소스다운로드
<html>
<head>
<title>Basic Grid</title>
<link rel="stylesheet" type="text/css" href="http://techbug.tistory.com/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="basicGrid.js"></script>
</head>
<body id="basicGridBody">
<div id="DIV_GRID_HERE"></div> <!-- Grid를 렌더링 할 위치 -->
</body>
</html>
Step1에서 배열데이타를 사용할때(Ext.data.SimpleStore)와 직접 통신하여 사용할때(Ext.data.Store)를 비교하면서 아래 소스를 보기 바란다.
Simplestore 는 기본적으로 네트웍을 사용하지 않으므로 Proxy를 사용하지 않는다. 그러나 Store, JsonStore, GroupingStore의 경우 Proxy를 사용하여 데이타의 위치를 지정할수 있다.
| SimpleStore | (Json, Grouping) Store |
Proxy | 없음(없을시 HttpProxy사용) | HttpProxy, ScriptTagProxy, MemoryProxy |
Reader | ArrayReader | JsonReader, XmlReader, ArrayReader |
Load Method | store.loadData(data); | store.load() |
Extend | Ext.data.Store | Ext.data.Store |
HttpProxy나 ScriptTagProxy로 서버 통신을 한다. ScriptTagProxy에 대한 고찰(?) 을 참조하라.
위의 convert 와 renderer 옵션을 이용하여 여러가지 다양한 형태의 grid 생성이 가능하다. 또한 JsonReader의 root 노드또한 Json 표기 형식의 . (dot) 연산자로 해당 자식 노드를 가져올수 있다.
추가적으로 extjs의 API Doc에는 rederer에 대해서 다음과 같이 기술하고 있다.
rederer의 파라미터값들
* value : Object - 셀에 들어가는 데이타
* metadata : Object - 정의한 객체 메타데이타
* css : String : 테이블테그에서 td에 먹이는 css
* attr : String : HTML 애트리뷰트 정의
* record : Ext.data.record : 데이타가 압축된 레코드
* rowIndex : Number
* colIndex : Number
* store : Ext.data.Store
데이타스토어가 모두 로드가 완료됐을 경우 혹은 서버이상으로 로드가 되지 않았을 경우를 예를 들어 설명한다.
BasicGridClass = function(){
return {
init: function(){
//데이타 스토어 정의
this.store = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: 'basicGrid.json'
}),
sortInfo: {
field: 'price',
direction: "DESC"
},
reader: new Ext.data.JsonReader({
root: 'testData'
}, [{
name: 'company',
type: 'string',
mapping: 'company'
}, {
name: 'price',
type: 'float',
mapping: 'price'
}, {
name: 'change',
type: 'float',
mapping: 'change'
}, {
name: 'pctChange',
type: 'float',
mapping: 'pctChange'
}, {
name: 'lastChange',
type: 'date',
dateFormat: 'n/j h:ia',
mapping: 'lastChange'
}])
});
this.grid = new Ext.grid.GridPanel({
store: this.store,
columns: [{
id: 'company',
header: "Company",
width: 160,
sortable: true,
dataIndex: 'company'
}, {
header: "Price",
width: 75,
sortable: true,
renderer: 'usMoney',
dataIndex: 'price'
}, {
header: "Change",
width: 75,
sortable: true,
dataIndex: 'change'
}, {
header: "% Change",
width: 75,
sortable: true,
dataIndex: 'pctChange'
}, {
header: "Last Updated",
width: 85,
sortable: true,
renderer: Ext.util.Format.dateRenderer('m/d/Y'),
dataIndex: 'lastChange'
}],
stripeRows: true,
autoExpandColumn: 'company',
loadMask: {
msg: '데이타 로드중'
},
sm: new Ext.grid.RowSelectionModel({
singleSelect: true
}),
view: new Ext.grid.GridView({
forceFit: true,
enableRowBody: true,
ignoreAdd: true,
emptyText: 'No Record found'
}),
height: 350,
width: 800,
title: '기본 그리드'
});
this.grid.render('DIV_GRID_HERE');
//this.grid.getSelectionModel().selectFirstRow();
this.store.load();
this.grid.on('rowcontextmenu', function(grid, index, e){
alert('오른쪽 버튼 클릭');
}, this);
// Row에서 마우스 오른쪽 클릭시
this.grid.on('rowclick', function(grid, index, e){
alert('클릭');
}, this);
// Row 클릭시
this.grid.on('rowdblclick', function(grid, index, e){
alert('더블클릭');
}, this);
// Row 더블클릭시
this.gsm = this.grid.getSelectionModel();
// 데이타 스토어에서 데이타 로드 완료시 첫번째 Row 선택되게하기
this.store.on('load', this.gsm.selectFirstRow, this.gsm);
this.store.on('load', function(store, records, options){
alert('데이타로드완료')
}, this);
// 데이타 스토어에서 데이타 로드실패시 exception throw
this.store.on('loadexception', function(a, conn, resp){
//alert(resp.status.toString() +'\n'+ resp.statusText);
this.grid.emptyText = 'data load error';
}, this);
// Ext.data.Dataproxy 통신 에러시
this.store.proxy.on('loadexception', function(proxy, dataObj, callbackArgs, e){
if (Ext.gecko)
console.log(e);
});
}
}
}
();
Ext.EventManager.onDocumentReady(BasicGridClass.init, BasicGridClass, true);
BasicGridClass = function(){
return {
init: function(){
//데이타 스토어 정의
this.store = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: 'basicGrid.json'
}),
sortInfo: {
field: 'price',
direction: "DESC"
},
reader: new Ext.data.JsonReader({
root: 'testData'
}, [{
name: 'company',
type: 'string',
mapping: 'company'
}, {
name: 'price',
type: 'float',
mapping: 'price'
}, {
name: 'change',
type: 'float',
mapping: 'change'
}, {
name: 'pctChange',
type: 'float',
mapping: 'pctChange'
}, {
name: 'lastChange',
type: 'date',
dateFormat: 'n/j h:ia',
mapping: 'lastChange'
}])
});
this.grid = new Ext.grid.GridPanel({
store: this.store,
columns: [{
id: 'company',
header: "Company",
width: 160,
sortable: true,
dataIndex: 'company'
}, // DataIndex정의
{
header: "Price",
width: 75,
sortable: true,
renderer: 'usMoney',
dataIndex: 'price'
}, {
header: "Change",
width: 75,
sortable: true,
dataIndex: 'change'
}, {
header: "% Change",
width: 75,
sortable: true,
dataIndex: 'pctChange'
}, {
header: "Last Updated",
width: 85,
sortable: true,
renderer: Ext.util.Format.dateRenderer('m/d/Y'),
dataIndex: 'lastChange'
}],
stripeRows: true,
autoExpandColumn: 'company',
loadMask: {
msg: '데이타 로드중'
},
//RowSelectionModel 이거나 CellSelectionModel일 경우만 데이타 가져오기
sm: new Ext.grid.RowSelectionModel({
singleSelect: true
}),
view: new Ext.grid.GridView({
forceFit: true,
enableRowBody: true,
emptyText: 'No Record found'
}),
height: 350,
width: 800,
title: '기본 그리드'
});
this.grid.render('DIV_GRID_HERE');
this.store.load();
this.gsm = this.grid.getSelectionModel();
this.store.on('load', this.gsm.selectFirstRow, this.gsm);
// ① Row에서 오른쪽 마우스 클릭했을 경우
this.grid.on('rowcontextmenu', this.getRowData, this);
// ① Row 클릭했을 경우
this.grid.on('rowclick', this.getRowData, this);
// ① Row 더블클랙했을 경우
this.grid.on('rowdblclick', this.getRowData, this);
// ① Row가 선택됐을 경우
this.gsm.on('rowselect', this.rowSelect, this);
},
getRowData: function(thisGrid, rowIndex, eventObject){
// ② 클릭,컨텍스트,더블클릭시 해당 이벤트가 일어난 Row의 Record가져오기
var record = this.store.getAt(rowIndex) || this.gsm.getSelected();
// ③ 선택된 레코드에서 데이타 가져오기
alert(record.data.company + '\n' + record.get('company'));
},
// ④ rowSelectionModel에서 선택된 Row의 데이타 가져오기
rowSelect: function(selectionModel, index, record){
alert(record.data.company + '\n' + record.get('company'));
}
}
}
();
Ext.EventManager.onDocumentReady(BasicGridClass.init, BasicGridClass, true);
데이터스토어.getAt(Row의 Index Number) - 데이타 스토어의 인덱스에서 가져오는 방법
셀렉션 모델.getSelected() - RowSelectionModel이나 CellSelectionModel에서 가져오는 방법
레코드.data.가져올DataIndex텍스트
레코드.get('가져올DataIndex텍스트)
Extjs 기본레이아웃에 grid panel 붙이기 (0) | 2008.02.25 |
---|---|
Extjs Apatana ext2.0 plugin (0) | 2008.02.25 |
Extjs 레이아웃에서 center region 숨기기 꽁수 (0) | 2008.02.22 |
Extjs 그리드안에서 프로세스바 구현하기 (3) | 2008.02.21 |
Extjs 프로세스바 구현하기 (0) | 2008.02.21 |
기본적으로 ExtJS의 레이아웃을 잡을때 Center Region은 Hide/show 및 Collapse/Expand가 되지 않으나 해당 Center Region을 감추는 방법에 대해서 기술한다. (꼼수). 단, 해당 꼼수(^^)는 fullscreen이거나 전체 사이즈가 고정되어 있다고 전제하에 동작한다. 만약 좌측패널이 전체 화면으로 center region을 감췄을때 브라우저 사이즈를 줄이거나 한다면 다시 syncSize해줘야 한다.
<html>
<head>
<title>Basic Layout</title>
<link rel="stylesheet" type="text/css" href="http://techbug.tistory.com/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>
// body container의 id(basicLayoutBody)를 이용하여 전체 화면사이즈를 가져온다.
</html>
Extjs Apatana ext2.0 plugin (0) | 2008.02.25 |
---|---|
Extjs Grid panel 및 데이타 축출하기 (8) | 2008.02.22 |
Extjs 그리드안에서 프로세스바 구현하기 (3) | 2008.02.21 |
Extjs 프로세스바 구현하기 (0) | 2008.02.21 |
Extjs을 이용한 특정이벤트 컨텍스트 메뉴달기 (0) | 2008.02.21 |
BCF
에서는 Ext.Viewport를 이용하여 Layout을 잡는것을 기본으로 한다. Ext.Viewport는 브라우저의
Viewport(<body></body>)영역에 자동으로 document Body에 렌더링하는 유틸리티
컨테이너 클래스이다. 브라우저의 크기가 변경되었을때 자동으로 레이아웃을 재계산하여 full-screen으로 렌더링한다.
주의 : Viewport는 document.body에 다른 어떤 container와 같이 렌더링 할수 없다. 페이지당 단 한개의 Viewport만 사용된다.
north | ||||
west | east | |||
center | ||||
south |
브 라우저에서 위와 같이 그리드를 갖추고 있다고 하면 Viewport에서는 north, west,east,south,center 라는 영역(Region)을 갖는 5개의 Panel이 자동으로 생성된다. 위의 영역중 Center를 제외하고는 모두 Collapse/Expand 및 Hide/show 가 가능하다. 레이아웃을 생성할때에는 반드시 Center Region이 하나 이상(Center Region이 TabPanel 일 경우 여러개 존재) 존재하여야 한다.
기본적으로 아래 소스에서 사용되어질 레이아웃 종류는 BorderLayout이다. 이전 장을 반드시 숙지할것
최종 소스 : 다운로드
각 소스는 이미 설명했던 0010. Basic Structure와 0020.Basic Format을 이용하여 재사용성을 고려하여 만든다.
<html>
<head>
<title>Basic Layout</title>
<link rel="stylesheet" type="text/css" href="http://techbug.tistory.com/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>
BasicLayoutClass = function() {
return {
init : function() {
this.viewport = new Ext.Viewport( {
layout : 'border',
items : [// Step 1에서 정의된 좌측 패널 :this.WestPanel = new Ext.Panel({
//Step1에서는 Default 값인 new Ext.Panel() 이 생략됨
region : 'west',
title : 'WEST',
collapsible : true,//초기 로딩시 collapse된 상태에서 보여진다.width : 250,
collapsed : true,
split : true,
layout : 'fit',
margins:'5 0 5 5',
cmargins : '5 5 5 5',
html : '좌측'
}),
this.CenterPanel = new Ext.Panel({
region : 'center',
title : 'CENTER',
layout : 'fit',
margins:'5 5 5 0',
html : '중간'
})
]
});
this.viewport.doLayout();
this.viewport.syncSize();
}
}
}();
Ext.EventManager.onDocumentReady(BasicLayoutClass.init, BasicLayoutClass, true);
LeftArea = function(){
//기존 좌측 판넬의 config option을 그래도 호출하여 사용
LeftArea.superclass.constructor.call(this,{
region : 'west',
title : 'WEST',
collapsible : true,
collapsed:false,
width : 250,
split : true,
layout : 'fit',
margins:'5 0 5 5',
cmargins : '5 5 5 5',
html : '좌측'
});
};
Ext.extend(LeftArea, Ext.Panel,{
//Ext.Panel을 상속받아 사용하였다, GridPanel일 경우는
//Ext.grid.GridPane을 사용하듯이 여러 Panel정의하여 사용가능
//Left Area의 Public,Private,Privileged 메쏘드를 정의한다.
});BasicLayoutClass = function() {
return {
init : function() {
this.viewport = new Ext.Viewport( {
layout : 'border',
items : [
// LeftArea Class로 별도로 선언
this.WestPanel= new LeftArea(),
this.CenterPanel = new Ext.Panel({
region : 'center',
title : 'CENTER',
layout : 'fit',
margins:'5 5 5 0',
html : '<div id="_CONTENTS_AREA_">컨텐츠 영역입니다.</div>'
})
]
});
this.viewport.doLayout();
this.viewport.syncSize();
}
}
}();
Ext.EventManager.onDocumentReady(BasicLayoutClass.init, BasicLayoutClass, true);
Extjs를 이용한 에러핸들링 (2) | 2008.02.18 |
---|---|
Extjs 서로 다른 도메인일 경우 ScriptTagProxy를 이용한 Ajax통신 (5) | 2008.02.18 |
Extjs Sample :: 기본문서구조만들기 (0) | 2008.02.18 |
Extjs Sample :: 기본문서구조 (0) | 2008.02.18 |
Extjs Qtips 사용하기 (0) | 2008.02.18 |
이 튜토리얼을 공부하기 위한 가장 좋은 방법은 파이어폭스와 파이어버그를 바로 곁에 두는 것입니다. 이 방법으로 본 튜토리얼내의 예제를 즉시 테스트 해볼 수 있습니다.
만약 아직 가지고 있지 않다면 두 가지 모두 설치 하세요.
scope
1. (명사) 어떤 활동 혹은 작업 또는 힘을 가지거나 제어를 할 수 있는 지역 [1]
2. (명사) 프로그램 내에서 변수의 접근 범위; 예를 들어 어떤 함수가 다른 함수에서 생성된 변수를 사용할 수 있는지 여부. [2]
함수 실행 시 어디에 있는 변수에 접근이 가능 한지 찾는 중에 누군가가 "이건 스코프 문제야" 혹은 "이건 잘못된 스코프에서 실행 중이야" 라고 하거나 그와 비슷하게 이야기를 하면 우리는 어떻게 이것을 처리해야 할까요?
사실 자바스크립트 내에서 선언된 함수들은 객체에 소속된 메소드들 입니다. 아래와 같이 코드를 작성하더라도 말이죠:
function fn() { alert(11); }
제가 농담을 하고 있다고 말하시겠죠. 하지만 이게 진짜 진실인지 아주 쉽고 간단하게 증명 해낼 수 있습니다. 이 예제를 위해서 어떠한 자바스크립트 파일이나 서버, 혹은 html이 필요치 않습니다. 단지 파이어폭스를 열고 파이어버그의 하단 윈도우를 열어서 콘솔 탭을 클릭하고 브라우저의 status 바 바로 위에 >>> 입력란에 코드를 입력하면 됩니다.
아래와 같이 입력하고:
function fn() { alert(11); };
엔터를 입력하면 아무 반응이 없습니다. 그렇죠? fn 함수만 선언 한 것이지요. 다음과 같이 입력합니다:
fn();
엔터를 입력하면 11이 적힌 경고 창을 볼 수 있습니다. 여기까지 잘 따라 오셨습니다. 다시 입력해봅시다:
window.fn(); this.fn();
같은 결과가 보이나요? 함수 fn은 window 객체의 메서드가 된 것을 알 수 있고 두 번째 라인은 this 변수가 window 객체를 가리키고 있다는 사실을 증명합니다. 이런고로 자신의 함수를 window.myFunction(...)처럼 호출할 필요가 없다는 것이죠. 이것은 편리하기도 하고 게으른 프로그래머들의 일을 덜어줍니다.
window 객체는 항상 존재하며 브라우저 윈도우 그 자체 라고 생각 하시면 됩니다. 이것은 document 객체와 전역(global)으로 선언된 모든 변수와 같은 다양한 객체를 담고 있습니다.
다시 파이어버그를 열어서 Script 탭으로 변경 시키고 우측에 "New watch expression..." 라고 적혀 있는 박스에 window 라고 입력 합니다. 그러면 window 객체에 어떤 것들이 있는지 살펴 볼 수 있습니다.
특히 방금 전 선언했던 fn 함수를 찾아 보시기 바랍니다.
각각의 frame 혹은 iframe은 자신만의 고유한 영역에서 독립적인 window 객체를 가지고 있습니다.
이제 조금 더 어려운걸 해봅시다. 다시 파이어버그의 Console 탭을 선택하고 다음과 같이 입력합니다:
var o1 = {testvar:22, fun:function() { alert('o1: ' + this.testvar); }}; var o2 = {testvar:33, fun:function() { alert('o2: ' + this.testvar); }};
우리가 무엇을 한 것일까요? 객체 o1 과 o2 를 선언했고 이 둘은 같은 이름의 프로퍼티와 메서드를 가지고 있지만 각각의 프로퍼티는 다른 값을 가지고 있습니다.
아래와 같이 입력합니다:
fun(); window.fun(); this.fun();
에러가 발생하지요? 좋습니다. window 객체(this와 동일)는 fun 메소드를 가지고 있지 않습니다. 아래와 같이 해보세요:
o1.fun(); o2.fun();
이제 22와 33이 보이죠? 아주 좋습니다!
이제 이 복잡한 부분의 마지막입니다. 지금까지는 간단한 함수들을 사용했고 그래서 개별 객체의 타입(type)에 대해서 신경 쓸 필요가 없었습니다. 하지만 o1.fun 이 아주 기능이 많고 지난주부터 작업해서 이제 마지막 작업 단계에 있다고 칩시다. 코드 내에 산재해 있는 this 변수가 100 라인 정도 된다고 상상해 보자 구요. o1.fun을 호출(실행)시 this가 o2를 가리키고 있다면 어떻게 해결해야 할까요? 아래와 같이 입력해봅시다:
o1.fun.call(o2);
o1의 fun 메소드가 실행 중 일 때 강제로 변수 this 가 o2를 지정되게 설정된걸 보셨나요? 좀더 유식하게 말하면 다음과 같습니다: 메소드 o1.fun이 객체 o2의 스코프(scope)내에서 실행 된다
정리하면 스코프는 어떤 객체의 메서드로서 함수가 실행 중 일 때 this 변수의 값이다 라고 생각하시면 될 것 같습니다.
변수의 가시범위는 이전 단락인 스코프 항목과 밀접한 관계에 있습니다. 우리는 이미 변수(함수를 포함한 모든 변수)가 어떤 객체나 함수 밖에 선언되면 전역으로 등록 된다고 알고 있습니다. 기술적으로 다시 말하면 window 객체의 전역 프로퍼티가 되는 것이지요.
전역 변수들은 어디에서든지 보입니다;어떤 함수들의 안에서든 밖에서든. 만약 하나의 함수에서 전역 변수를 수정하게 되면 다른 함수들은 변경된 값을 보게 됩니다.
이제 객체가 자신만의 고유한 프로퍼티(앞서 testvar 예제처럼)를 갖는다는 걸 알 수 있게 되었습니다. 이것은 객체의 안과 밖에서 접근 가능한데, 맞는지 직접 시험해 봅시다:
alert(o1.testvar); // o1의 프로퍼티인 testvar를 외부에서 접근
내부에서 접근하는 것은 아까 두 개의 fun 메소드 시연에서 이미 해봤으므로 그냥 넘어 갑니다.
이제 마지막으로 남은 퍼즐의 조각은 지역 변수는 함수 내에서 var 키워드와 같이 선언 되어야 한다는 겁니다:
i = 44; function fn2() { var i = 55; alert(i); } fn2();
어떤 것을 보았나요? 55 이지요. 변수 i 는 fn2 내에 선언 되어 fn2의 지역 변수가 되었고 44가 들어있는 전역 변수인 i 에 접근하지 않습니다.
하지만 이렇게 하면:
alert(i);
전역 변수 i 에 접근하기 때문에 44가 나오는 것을 볼 수 있습니다.
이 문서가 스코프와 변수 가시범위 공부에 많은 도움이 되길 바랍니다.
더 읽을만한 것들:
Extjs 기본 DomQuery (0) | 2008.02.18 |
---|---|
Extjs 초보자를 위한 애플리케이션 레이아웃(2.02) (8) | 2008.02.17 |
ExtJS Tutorial (1) | 2008.02.17 |
ExtJS 시작하기 (8) | 2008.02.17 |
ExtJS 개발하기 위해 선행되는 지식들 (7) | 2008.02.15 |
ExtJs는 웹애플리케이션을 만들기위한 client-side-JavaScript framework이다. JackSolocum이 Yahoo! User Interface (YUI) library의 확장으로 만들기 시작했으며 Yui-ext란 Project명으로 빠르게 성장했다.
ExtJS는 개발목적의 오픈소스로 제공되는 LGPL 라이센스와 로얄티프리 커머셜 라이센스로 구분된다.( licensing page )
상업용 라이센스는 SVN 접속이 허락되며 전화/팩스 및 이메일로 지원을 받을수 있는것이 고작(?)이다.
PHP,Ruby on Rails (Embeded로 지원), .NET, Java 등 여러가지 서버 플랫폼을 지원한다. 사이트( server-side frameworks ) 를 참조하기 바란다.
1.0.1a 버전에서는 YUI, jQuery or Prototype/Script.aculo.us. 가 반드시 필요했으나 1.1에서는 Ext adapter를 채택하여 더이상 다른 외부 라이브러리 없이 구동할수 있다. 또한 외부 라이브러리를 사용하고 싶다면 해당 라이브러리 어답터가 별도로 구비되어 있으며 Extension Mode로 제공되는 기타 다른 라이브러리를 참조할수가 있다.
Base Library | Include Order | Get Library |
---|---|---|
Ext Standalone | ext-base.js ext-all.js (or your choice of files) |
http://www.extjs.com/download |
Yahoo! UI (.12+) | yui-utilities.js (or your choice of YUI base files) ext-yui-adapter.js ext-all.js (or your choice of files) |
http://developer.yahoo.com/yui/ |
jQuery (1.1+) | jquery.js jquery-plugins.js // required jQuery plugins ext-jquery-adapter.js ext-all.js (or your choice of files) |
http://jquery.com/ http://docs.jquery.com/Plugins |
Prototype (1.5+) / Scriptaculous (1.7+) |
prototype.js scriptaculous.js?load=effects (or whatever you want to load) ext-prototype-adapter.js ext-all.js (or your choice of files) |
http://www.prototypejs.org/ http://script.aculo.us/ |
var myExample = function()
{
return
{
foo: 'bar',
boo: 'far'
}
};
위의 코드는 아래와 같이 작성해야 한다.
var myExample = function()
{
return {
foo: 'bar',
boo: 'far'
}
};
만일 여의치 않다면 다음과 같이 대처한다.
아래와 같이 HttpProxy보다는 ScriptTagProxy를 사용한다.
var proxy = new Ext.data.HttpProxy({
url: '/DoSearch.php'
});
// Add the HTTP parameter searchTerm to the request
proxy.on('beforeload', function(p, params) {
params.searchTerm = searchValue;
});
See http://extjs.com/forum/showthread.php?t=11698#2 or http://extjs.com/forum/showthread.php?t=6710#2
function(grid, rowIndex, columnIndex, e) {
var record = grid.getStore().getAt(rowIndex); // 레코드의 Row를 가져온다.
var fieldName = grid.getColumnModel().getDataIndex(columnIndex); // 컬럼의 필드명을 가져온다.
var data = record.get(fieldName);
}
Ext.Updater.defaults.loadScripts나 Updater.update 메쏘드나 Element.update 메쏘드 사용
HttpProxy나 ScriptTagProxy와 같이 remote data 를 사용할때 Store.load() 는 비동기로 호출되며 서버블로킹없이 즉시 요청한다. "load" 와 "loadexception"이벤트로 쉽게 작업을 할수 있다. 이후 Grid Data Load에서 설명 ^^
Ext.get 는 단지 HTML Element의 객체를 가져온다. 즉, document.getElementById와 같다.
판넬이나 폼판넬등 컴포넌트를 불러올때는 Ext.getCmp를 사용해야 한다.
myNode.appendChild(new AsyncTreeNode({
text: "A folder",
iconCls: "folder"
});
CSS의 class seletor를 이용한다. (CSS 표준을 항상 염두해 둘것....)
.x-tree-node img.folder, .x-tree-node-collapsed img.folder{
background: url("../images/default/tree/folder.gif");
}
.x-tree-node-expanded img.folder {
background: url("../images/default/tree/folder-open.gif");
}
당근 ext-all.js 파일의 패쓰가 잘못됐으니 확인해야지....쩝..이런것도 적어야 하나..
<script type="text/javasscript" src="/somepath.js"></script>
<script type="text/javascript" src="/somepath.js"></script>
해당 엘리먼트 id값을 찾을수 없다는 얘기다. 아래에서는 id='save-button'를 가진 객체를 찾을수 없다는 얘기다.
// constructors:
var tb = new Ext.Toolbar('toolbar');
// creating Element references:
var saveBtn = Ext.get('save-button');
<div id="toolbar"></div>
<input id="save-button" type="button" value="Save" />
1x1pixel짜리 투명이미지를 절케 표시하고 있다. 잘 해두도록...
Ext.BLANK_IMAGE_URL = '/images/ext/resources/images/aero/s.gif'; // 1.1
Ext.BLANK_IMAGE_URL = '/images/ext/resources/images/default/s.gif'; // 2.0
쉼표를 잘 찾아보도록....
testFunc = function() {
return {
titlebar: true,
collapsible: true, // <--- BOOM goes the comma! :D
}
}
JSLint를 이용하면 쉽게 찾을수 있다.
이런경우 난감한...문제가 발생할수도 있는데 나의 경우는 전체 화면을 다시 그린적도 있다.. ㅠ.,ㅠ;
반드시 해당 컴포넌트(판넬,폼판넬, 콤보박스, 그리드 판넬)의 ID값을 반드시 입력해 준다. 또한 같은화면에 같은 ID값을 가진 객체가 있는지 반드시 확인한다.
- ExtJS Forum에 들어가 도움을 청해본다. 그리고 Google 신에게 물어본다. 답이 다 있다. 다만 시간이 걸릴뿐이다.
영어 해석은 기본, 중국어은 옵션.. ^^;
위의 내용만 알면 어느정도 ExtJS를 사용하면서 겪을 문제를 반정도는 해결할수 있다... 나의 경우 그랬으니깐... ㅡ.,ㅡ;
끝.
Extjs 기본 DomQuery (0) | 2008.02.18 |
---|---|
Extjs 초보자를 위한 애플리케이션 레이아웃(2.02) (8) | 2008.02.17 |
Extjs scope에 대한 고찰 (2) | 2008.02.17 |
ExtJS Tutorial (1) | 2008.02.17 |
ExtJS 개발하기 위해 선행되는 지식들 (7) | 2008.02.15 |
Ext JS 은 yui-ext에서 부터 시작되었다. 아래 사이트에서 YUI에 대해서 좀 봐두는것도 좋을지도..
ExtJS를 서버사이드 프레임웍으로 사용한 녀석들.....
대표적인 샘플코드는 모두 PHP코드로 되어 있는 걸 보면 PHP에서 개발하기 가장 쉬운것 같음.
ExtJS 내장 PHP프레임웍 : Qcodo Development Framework
Direct Web Remoting (DWR) : http://getahead.org/dwr
Ext plugin - ROR는 내장 플러그인으로 작동하므로 gem을 이용해 받으면 되겠다... (찾기가 더 힘드네.. ㅡ.,ㅡ;)
Eclipse 은 오픈소스 통합개발툴 (among other things!)이다. ExtJS개발을 위해 이클립스를 사용하기 위해서는 먼저 자바스크립트 사용할수 있는 플러그인을 설치해야 한다.
아래의 플러그인을 추천한다.
위에 열거된 플러그 인들은 각자 자바스크립트 에디터를 포함하고 있다. 자바스크립트를 열때 "Open with"로 열어서 사용하도록...플러그인을 선택할때는 코드 assist를 지원하는지 확인해 봐야 할듯
Firebug는 Firefox에 애드온되어 작용하는데 웹페이지의 내용(CSS,HTML,Javscript등)을 실시간으로 볼수있는 상당히 매력적인 도구이다.
Screencasts
Tutorials
다른 브라우저에서 Firebug console을 이용하기
피들러는 서버와 PC사이의 HTTP 트래픽 로그를 볼수 있는 디버깅 프록시이다. IE전용이나 Firefox의 proxy고급옵션에서 사용할수 있으며 자신이 원하는대로 필터링 하여 사용할수 있다.
SQL,CSV,xml, excel등 테스트 데이타를 생성해준다.
YSlow는 rules for high performance web sites를 기반으로 현재 페이지의 속도를 분석해준다. YSlow 는 Firefox 애드온 프로그램으로 인기가 있다.Firebug web development tool.
http://www.debugbar.com/?langage=en
Extjs 기본 DomQuery (0) | 2008.02.18 |
---|---|
Extjs 초보자를 위한 애플리케이션 레이아웃(2.02) (8) | 2008.02.17 |
Extjs scope에 대한 고찰 (2) | 2008.02.17 |
ExtJS Tutorial (1) | 2008.02.17 |
ExtJS 시작하기 (8) | 2008.02.17 |