반응형

[ExtJs] 튜토리얼 1

  2008/07/17 16:44:31 초급 프로젝트 만들기

 1단계 :

extjs001.jpg다음과 같이 ExtJS 라이브러리를 사용할 때는


[파일명].css -> 디자인 정의

[파일명].html -> ExtJs 라이브러리를 사용하기 위해 스크립트로 선언해줘야 한다.

[파일명].js  -> 실제 구동되는 내용이 들어간다.


세개의 파일을 만드는게 기본 구조이다.


본 화면은 Aptana 스튜디오 화면이다. 개발을 할때는 FireFox에 FireBug 플러그인을 설치하여

콘솔로 테스트를 해보는걸 권장한다.



2단계 :

테스트용이기 때문에 applayout.js 에는 아무 내용이 들어있지 않다. 콘솔 테스트 시에는 FireBug를 이용한다.

FireBug를 실행할 때는 FireFox 에서 F12 키를 눌러주면 된다.

테스트 서버 URL : http://aha.chonbuk.ac.kr/extJsTest/widget/applayout.html

  1. applayout.css
  2. body {
       font-family:verdana,tahoma,helvetica;
       padding:0px;
       padding-top:0px;
       font-size:13px;
       background-color:#fff !important;
    }

  1.  applayout.html
  2. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
     <head>
      <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
      <title>Untitled Document</title>
     
      <link rel="stylesheet" type="text/css" href="lib/ext/resources/css/ext-all.css" />
  3.   <!-- GC -->
      <!-- LIBS -->    
         <script type="text/javascript" src="lib/ext/adapter/yui/yui-utilities.js"></script>
         <script type="text/javascript" src="lib/ext/adapter/yui/ext-yui-adapter.js"></script>
      <!-- ENDLIBS -->
         <script type="text/javascript" src="lib/ext/ext-all-debug.js"></script>
     
      <!-- Common Styles for the examples -->
      <link rel="stylesheet" type="text/css" href="applayout.css" />
     </head>
     <body>
     </body>
    </html>

3단계:

FireFox에서 FireBug의 콘솔을 이용하여 테스트를 해볼 수 있다.

  1. Ext.get(document.body).update('<div id="test">테스트</div>'); <- body 태그 안에 내용을 갱신한다.

extjs002.jpg 


4단계: 작업 패널을 만들어 본다.

  1. Ext.get(document.body).update('<div id="test">테스트</div>');
  2. new Ext.Panel({              //<- 다음과 같이 윈도우 하나를 띄워준다.
       renderTo: 'test',            //<- 윈도우를 그릴 레이어 id 를 적어준다.
       width: '200px',               //<- 윈도우의 가로 사이즈를 나타낸다.
       title: 'My Title',               //<- 프레임 타이틀 이름을 표시한다.
       html: 'My HTML content'   //<- 실제적인 컨텐츠가 들어가는 부분이다.
    });

 extjs003.jpg


5단계 : 작업 패널의 확장 속성을 주어보자!

파란색 상자로 쳐진 부분이 새로 추가한 내용이다. 작업화면에 다음과 같이 확장 가능한 화면이 표시된다.

 extjs004(1).jpg


6단계 : API 에서 필요로 하는 탭 기능으로 워크 스페이스 구현할 예제를 한번 만들어보았다

다음과 같이 Ext.TabPanel() 을 이용하면 다음과 같은 화면이 그려지게 된다. 생각보다 깔끔하게 잘 나온다.

extjs005.jpg 


7단계 : 탭패널을 이용하여 워크스페이스 만들어보기

extjs006.jpg 탭 워크스페이스 예제의 구성 파일은다음과 같다

loripsum.html : 새로운 탭이 만들어질때 씌여지는 컨텐츠가 들어간다. 우선 아무 내용이나 집어넣었다.

sample0.html, sample1.html : 탭뷰가 갱신되는걸 표시하기 위한 컨텐츠, 우선 아무 내용이나

tab_actions.js : 탭 워크스페이스를 구현하는 자바스크립트 소스

tabLayout.html : 탭 워크스페이스의 레이아웃
















 탭 워크스페이스를 구현한 그림이다.

워크스페이스를 갱신하면 원래 있던 내용이 바뀐다.

새로운 워크스페이스를 추가하면 탭 워크스페이스가 늘어난다.

테스트 URL : http://aha.chonbuk.ac.kr/extJsTest/widget/tabLayout.html


extjs007(1).jpg 

  1. tabLayout.html
  2. <html>
    <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <title>TabPanel Tutorial</title>
     <!-- Ext CSS and Libs -->
     <link rel="stylesheet" type="text/css" href="lib/ext/resources/css/ext-all.css" />
     <script type="text/javascript" src="lib/ext/adapter/ext/ext-base.js"></script>
     <script type="text/javascript" src="lib/ext/ext-all.js"></script>
     
     <!-- Custom CSS and Libs -->
     <script type="text/javascript" src="./tab_actions.js"></script>
     <link rel="stylesheet" type="text/css" href="shared/share.css" />
     <style>
     #actions li {
      margin:.3em;
     }
     #actions li a {
      color:#666688;
      text-decoration:none;
     }
     </style>
    </head>
    <body>
  3. <ul id="actions" class="x-hidden">
     <li>
      <a id="use" href="#">워크스페이스 갱신</a>
     </li>
     <li>
      <a id="create" href="#">새로운 워크스페이스 추가</a>
     </li>
    </ul>
     
    <div id="tabs"></div>
    </body>
    </html>

  1. tab_action.js
  2.  Ext.onReady(function(){
          // Menu containing actions
           var tabActions = new Ext.Panel({
            frame:true,
            title: '워크스페이스 관리',
            collapsible:true,
            contentEl:'actions',    
            titleCollapse: true
        });
     
        // Parent Panel to hold actions menu
        var actionPanel = new Ext.Panel({
            id:'action-panel',
            region:'east',                     //<-자바의 레이아웃 구분과 같다. north, west, east, south, center
            split:true,
            collapsible: true,
            collapseMode: 'mini',
            width:200,
            minWidth: 150,
            border: false,
            baseCls:'x-plain',
            items: [tabActions]         //<-앞 서 만든 워크스페이스 관리 프레임을 패널에 집어 넣는다.
        });
     
        // Main (Tabbed) Panel
        var tabPanel = new Ext.TabPanel({
            region:'center',
            deferredRender:false,
            autoScroll: true,
  3.         enableTabScroll:true,     // <- 탭 이 화면에 다 표시 안될경우 좌우 스크롤 할 수 있게 해준다.
            margins:'0 4 4 0',
            activeTab:0,
            items:[{
                id:'tab1',
                contentEl:'tabs',
                title: '워크스페이스',
                closable:true,
                autoScroll:true
            }]
        });
       
        // Configure viewport
        viewport = new Ext.Viewport({
               layout:'border',
               items:[actionPanel,tabPanel]
        });
       
         // Adds tab to center panel
        function addTab(tabTitle, targetUrl){
            tabPanel.add({
                  title: tabTitle,
                  iconCls: 'tabs',
                  autoLoad: {url: targetUrl, callback: this.initSearch, scope: this},
                  closable:true
           }).show();
        }
     
        // Update the contents of a tab if it exists, otherwise create a new one
        function updateTab(tabId,title, url) {
         var tab = tabPanel.getItem(tabId);
         if(tab){
          tab.getUpdater().update(url);
          tab.setTitle(title);
         }else{
          tab = addTab(title,url);
         }
         tabPanel.setActiveTab(tab);
        }
     
        // Map link ids to functions
        var count = 0;
        var tabcount = 0;
        var actions = {
         'create' : function(){
          addTab('새 워크스페이스'+tabcount,'loripsum.html');
          tabcount++;
         },
         'use' : function(){
          // Toggle between sample pages
          updateTab('tab1','워크스페이스 갱신 ' + count + ' 회','sample'+(count%2)+'.html');
          count++;      
         }
        };
     
        function doAction(e, t){
         e.stopEvent();
         actions[t.id]();
        }
     
        // This must come after the viewport setup, so the body has been initialized
       
        actionPanel.body.on('mousedown', doAction, null, {delegate:'a'});          
    });




















Posted by 1010
반응형
[Source Link] 
Author: Brian Moeskau (변역:김재형)
Published: Novermber 1, 2007
Ext Version: 2.0
Last Modified: 2008.2.17 14:55
Summary: 2008.10.9 16:40 (Roundworld)


ExtStart.js

Ext.onReady(function(){
    alert("Congratulations! You have Ext configured correctly!");
});

Ext.onReady는 반드시 가장 처음으로 호출되는 메소드입니다. 모든 DOM의 로딩이 완료되어야 이 메소드가 자동으로 호출되므로 이 메소드 내부의 코드는 페이지 내 모든 엘리먼트에 접근이 가능합니다.


- Element: Ext 심장

var myDiv = document.getElementById('myDiv');

이 코드는 잘 실행되긴 하지만 여기서 반환되는 객체는(DOM node) 쓰기 쉽지는 않고 기능이 강력하지 않습니다. 반환된 node를 유용하게 사용하려면 많은 추가코드를 작성해야 합니다. 게다기 브라우저 별 호환성에 대해서도 고려를 해야하므로 짜증 만땅이라 할 수 있지요. (변역이 참 재밌습니다.)

이제 Ext.Element 객체를 살펴봅시다. 정말 Ext의 심장과도 같은 이 객체는 엘리먼트에 접근하거나 기능을 실행할고 할때 필요합니다.  Element API는 Ext 라이브러리에 입문하려고 할때 기초가 되며 여러분이 Ext에서 오직 하나의 클래스만 배울 시간만 가지고 있다면 Element를 선택하세요!

앞의 예제 코드에 대응되는 Ext Element로 ID를 얻어내는 코드는 아래와 같습니다.

Ext.onReady(function() {
    var myDiv = Ext.get('myDiv');
});

이제 Element 객체로 다시 돌아가서... 왜 흥미를 가져야 할까요?

1.Element 클래스는 대부분의 기존 DOM 매소드와 프로퍼티를 포함하고 있는데, 이로 인해 편리성, 통합성, 브라우저간 호환성이 있는 DOM 인터페이스를 얻게 됩니다.

2.Element.get() 메소드는 내부 캐쉬를 사용하며 따라서 동일한 객체를 반복해서 호출할 때 겁나(^^) 빠른 속도를 얻어 올수 있습니다.

3.브라우저간 호환성 문제가 없는 Element 메소드들을 통해서 DOM 노드에 대한 대부분의 작업이 수행됩니다.


- DOM node들 선택하기

종종 DOM 노드를 ID로 선택하는게 불가능 하거나 비효율적일 경우가 있습니다. 엘리먼트에 ID가 설정되어 있지 않거나 설정된 ID를 모를때, 혹은 ID로 참조할 요소가 너무 많을 경우에는 여러분은 엘리먼트에 설정된 어떤 프로퍼티 값이나 설정된 CSS 클래스명으로 선택한다던가하는 먼가 다른 방법이 필요할 겁니다. 이런 경우를 위해서 Ext에서는 DomQuery라고 불리는 극악 강력한(--;) DOM 선택 라이브러리를 제공합니다.

// Hightlights every paragraph
Ext.select('p').hightlight();   

예제는 Element.select를 아주 손쉽게 사용하는 방법을 보여줍니다. 여기서 반환되는 객체는 CompositeElement로 Element 인터페이스를 통하여 내부 엘리먼트에 접근할 수 있게 해줍니다. 이것은 반복문과 개별접근이 없이 Element.select로 손쉽게 모든 엘리먼트의 인스턴스를 리턴 받을수 있게 해줍니다.

DomQuery는 W3C CSS3 DOM selector의 기본 Xpath 그리고, HTML 프로퍼티를 포함하는 폭넓은 선택 옵션을 지원합니다.


- 이벤트 응답

지금까지 예제에서는 우리가 작성한 코드는 모두 onReady 함수 내에 직접 작성되었습니다. 이것이 뜻하는 바는 이것들은 항상 페이지의 로드가 완료된 즉시 실행이 된다는 것입니다. 이것은 우리에게 많은 제어권을 주지 못합니다. 여러분은 제어를 위해 코드가 특정 상황 혹은 이벤트에 응답하게끔 하고 싶을 겁니다. 이것을 하려면 이벤트 처리를 하는 함수를 이벤트 핸들러로 정의 해야합니다.

간단한 예제부터 시작하면 ExtStart.js를 열어서 아래와 같이 수정합니다.

Ext.onReady(function() {
    Ext.get('myButton').on('click', function() {
        alert("You clicked the button");
    });
});

코드는 아직까지 페이지가 로드 완료이후에 실행되지만 한가지 다른점은 함수내에 alert()이 선언되어 있는데 즉시 실행되지 않습니다. 이 부분은 버튼의 클릭 이벤트에 대한 "핸들러"로 지정되어 있기 때문입니다.

놀라지 마세요.(^^) Element.select는 같은 기능을 제공하지만 한번에 모든 요소 그룹을 가져올수 있습니다. 예를 들어, 우리 태스트 페이지 내에 모든 문단을 클릭 했을때 메시지를 보여주려면 다음과 같이 해봅시다.

Ext.onReady(function(){
    Ext.select('p').on('click',function(){
        alert("You clicked a paragraph");
    });
});

여기 두개의 예제 내에서 이벤트 처리함수는 함수명이 없이 단순히 인라인(inline)으로 선언되어 있습니다. 이러한 종류의 함수를 "익명함수(anonymous function)"라고 하는데 물론 이름이 있는 함수도 이벤트 처리용으로 할당 할 수 있습니다. 아래 예제 코드는 앞서의 예제와 동일한 기능을 수행합니다.

Ext.onReady(function(){
    var paragraphClicked = function(){
        alert("U clicked a paragraph");
    }
    Ext.select('p').on('click', paragraphClicked);
});

여기까지 우리는 이벤트가 발생되었을때 일반적인 처리를 하는 방법을 살펴 보았습니다. 하지만 이벤트가 발생한 엘리먼트 자체에 대한 어떤 액션을 실행하려고 할때, 해당 엘리먼트를 어떻게 알아 낼 수 있을까요?

물론 간단히 찾아 낼 수 있습니다.

Element.on 메소드는 이벤트 핸들링 함수에 3개의 완전 유용한 파라메터를 전달합니다.(여기서는 첫번째 1개만 살펴봅니다. 나머지는 API문서를 참조하세요.) 앞서 예제에서는 핸들링 함수에 파라메터가 생략되어 있습니다. 하지만 조금만 바꿔서 부가적인 기능을 추가시킬수 있습니다. 첫번째(가장 중요한) 파라메터는 발생된 이벤트입니다. 이것은 사실 Ext 이벤트 객체인데, 표준 브라우저 이벤트 보다 브라우저간 호환성이 있고 더욱 많은 정보를 제공합니다. 예를들어, 아래처럼 가단한 코드 추가만으로 이벤트의 traget으로 설정된 DOM 노드를 구할수 있습니다.

Ext.onReady(function() {
    var paragraphClicked = function(e){
        Ext.get(e.target).highlight();
    }
    Ext.select('p').on('click', paragraphClicked);
});

target이 DOM 노드라는 것을 기억하시고, 이제 이벤트가 발생된 엘리먼트를 구해서 원하는 액션을 수행할 수 있게 되었습니다. 예제를 실행해보면 모든 문단에 하이라이트가 되는 것을 볼수 있습니다.


- 위젯 사용하기

Ext는 지금까지 설명한 코어 자바스크립트 라이브러리 외에 추가적으로 풍부한 자바스크립트 UI위젯들을 제공합니다. 본 문서에서 설명하기에는 분량이 너무 많으므로 주로 사용되는 몇가지를 얼마나 쉽게 사용할수 있는지 알아보겠습니다.


1.MessageBox

지루한 "Hello World" 메시지 박스 띄우기 대신 다른것을 해 봅시다. 우리는 이전에 섹션에서는 각각 문단을 클릭했을때 하이라이트가 되는 코드를 작성했는데 이번에는 클릭했을때 나타나는 메시지 박스 안에 문장의 글이 보이게끔 수정해봅시다. 아래 paragraphClicked 함수를 고쳐봅시다.

Ext.get(e.target).highlight();

var paragraph = Ext.get(e.target);
paragraph.highlight();

Ext.MessageBox.show({
    title: 'Paragraph Clicked',
    msg: paragraph.dom.innerHTML,
    width: 400,
    buttons: Ext.MessageBox.OK,
    animEl: paragraph
});

여기서 다루어 볼만한 가치가 있는 몇가지 새로운 컵셉이 눈에 띠는군요. 첫라인에서 paragraph라는 이름으로 지역변수(전역변수 아닌가요? --;)를 생성 했으며 클릭이 발생한 DOM 노드의 엘리먼트 참조를 가지고 있게 했습니다.(이번에는 오직 <p> 태그들만 클릭 이벤트와 연계되므로 항상 입력되는 것을 알 수 있습니다.)

왜 이렇게 해야 할까요? 우리는 하이라이트 시키기 위한 엘리먼트의 참조가 필요하며 메시지박스를 위한 인자로 동일한 엘리먼트를 필요하기 때문입니다. 일반적으로 동일한 값 또는 객체 참조를 얻기 위해 동일한 함수를 여러번 호출하는 것은 나쁜습관(--;)이므로 지역 변수에 할당하여 재사용합니다. 이렇게 하면 우리는 착한 객체지향 개발자가 되는 겁니다!

이제 메시지박스호출 부분을 살펴봅시다. 또 다른 새로운 컨셉이 보이는데 단순히 메소드에 인자 리스트를 전달하는 것처럼 보이지만 자세히 살펴보면 매우 특이한 문법이 보일겁니다. 사실 MessageBox.show()에는 오직 하나의 인자만 전달되고 있는데 프로터피와 값의 집합을 담고 있는 객체 문자열(literal)입니다. 자바스크립트에서 객체 문자열은 이름/값 프로퍼티 리스트를 {}로 감싸서 언제든지 동적으로 생성시킬수 있습니다. 형식은 [프로퍼티 이름]:[프로퍼티 값] 으로 표기하며 이 패턴은 Ext 곳곳에서 널리 사용되기 때문에 금방 익술해질겁니다.

왜 객체 문자열(literal)을 사용하냐구요? 가장 큰 이유는 유연성입니다. 객체 문자열(literal)을 사용하면 아무때나 프로퍼티나 추가/삭제 되거나 순서가 변경되더라도 메소드의 시그니쳐(인자의 개수와 타입) 예를 들어 foo.action 이라는 가상의 메소드가 있다고 하고 네개의 옵션인자가 있다고 가정합니다. 그런데 오직 하나만 전달하는 상황이라면 코드를 다음과 같이 작성해야겠지요.

foo.action(null,null,null,'hello')

그러나 객체 문자열(literal)을 사용하게 된다면 다음과 같이 하면 됩니다.

foo.action(
    param4: 'hello'
})
 
무척 사용하기 쉽고 가독성도 더 좋습니다.


2.Grid

그리드는 Ext의 가장 인기있는 위젯 중 하나인데 사람들이 첫번째로 보고 싶어하는 것이기도 합니다. 자 이제 기초적인 그리드를 만들고 실행시키는 것이 얼마나 쉬운지 살펴보겠습니다. ExtStart.js 파일을 열어서 아래와 같이 코드를 수정해봅시다.

Ext.onReady(function() {
    var myData = [
                    ['Apple',29.89,0.24,0.81, '9/1 12:00am'],
                    ['Ext',83.81,0.28,0.34,'9/12 12:00am'],
                    ['Google',52.55,0.01,0.02,'7/4 1200am'],
                    ['Microsoft',52.55,0.01,0.02,'7/4 12:00am'],
                    ['Yahoo!',29.01,0.42,1.47,'5/22 12:00am']
    ];

    var myReader = new Ext.data.ArrayReader({}, [
                    {name: 'company'},
                    {name: 'price', type: 'float'},
                    {name: 'change', type: 'float'},
                    {name: 'pctChange', type: 'float'},
                    {name: 'lastChange', type: 'date', daeFormat: 'n/j h:ia'}
    ]);

    var grid = new Ext.grid.GridPanel({
                   store: new Ext.data.Store({
                            data: myData,
                            reader: myReader
                   }),
                   columns: [
                                 {header: "Company", width: 120, sortable: true, dataIndex: 'company'},
                                 {header: "Price", width: 90, sortable: true, dataIndex: 'price'},
                                 {header: "Change", width: 90, sortable: true, dataIndex: 'change'},
                                 {header: "% Change", width: 90, sortable: true, dataIndex: 'pctChange'},
                                 {header: "Last Updated", width:120, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
                  ],
                  viewConfig: {
                                 forceFit: true
                  },
                  renderTo: 'content',
                  title: 'My First Grid',
                  width: 500,
                  frame: true
});

grid.getSelectionModel().selectFirstRow();                  
});                                

코드가 길어 보이지만 실제로는 오직 4 line Code 뿐입니다. (태스트 데이타를 제외하면 3 Line Code)!

1.첫라인은 그리드에 보여줄 태스트 데이타를 생성, 실제로는 DB에서 데이타를 가져오겠죠.
2.다음은 데이터 리더를 생성하였는데 그리드 내 데이터 스토어에 담기 위해 데이터를 어떻게 읽어 들이고 레코드로 변환할지 설정합니다. 다양한 데이터 타입을 위한 각각의 리더 클래스가 있습니다.
3.다음으로 그리드 위젯을 생성하는데 아래와 같은 설정 값들을 전달합니다.
- 새로운 데이타 스토어, 생성한 태스트 데이터와 리더가 설정되어 있습니다.
- Columns에 칼럼 모델 정의를 합니다.
- 추가옵션으로 그리드의 기능 설정을 할수 있습니다.
4.마지막으로 SelectionModel을 사용해 첫번째 행을 하이라이트 시킵니다.

무척 간단하지요? (--;;) 잘 되었다면 아래와 같이 보일 겁니다.



물론 이런 코드를 가지고 자세한 부분까지 이해할 수는 없습니다. 이 예제의 목적은 풍부하고 시각적으로 복잡한 사용자 인터페이스 컴포넌트를 최소한의 코드만으로 작성할 수 있다는 것을 보여주는데 있습니다.

자세한 내용은 독자들의 숙제로 남깁니다. 그리드를 배우는데 도움이 되는 많은 내용들이 interactive grid damosGridPanel API documentation 에 포함되어 있습니다.



3.그리고 다른 것들...

지금 우리가 살펴본 것은 빙산의 일각(--;)에 불가합니다. Ext에 있는 수십개의 UI위젯들이 있습니다. 자동 페이지 레이아웃, 탭, 메뉴, 다이어로그, 트리뷰 등등. interactive examples 에서 모두 살펴보시기 바랍니다.



- Ajax 사용하기

페이지를 만들고 자바스크립트로 상호작용하는 것을 알게 되었습니다. 이제 여러분은 서버의 데이터베이스에서 가져오거나 저장하는 것과 같은 원격 서버에서 데이터를 가져오는 방법을 알고 싶을 겁니다. 자바스크립트를 이용하며 비동기적으로 페이지 리로딩 없이 처리하는 방식은 Ajax 라고 알려져 있는데 Ext는 Ajax를 지원합니다. 예를 들어 사용자와의 상호작용을 처리하여 서버에 비동기로 전송하고 응답하는 UI의 엘리먼트를 갱신하는 것인데 여기에 택스트 입력 박스, 버트, 메시지를 표시하기 위한 div를 포함하고 있는 간단한 HTML 폼으로 구성된 예제를 살펴봅시다.

ExtStart.html
<div>
    Name: <input type="text" id="name" />
    <input type="button" id="okButton" value="OK" />
</div>
<div id="msg"></div>

ExtStart.js
Ext.onReady(function(){
    Ext.get('okButton').on('click', function() {
        var msg = Ext.get('msg');
        msg.load({
                        url: 'ajax-example.php', //<-- change if nessary
                        params: 'name=' + Ext.get('name').dom.value,
                        text: 'Updating...'
        });
        msg.show();
    });
});

아마도 일반적인 패턴은 지금과 비슷하게 시작할겁니다! 이 코드는 okButton을 Element 객체로 래핑시키고 버튼 클릭 이벤트를 처리하는 익명함수로 연결시키고 있습니다. 클릭 핸들러 내에서는 Updater라고 불리우는 특별한 내부 클래스를 사용하는데 이 클래스는 손쉽게 Ajax 응답을 주고 받고 다른 엘리먼트를 갱신합니다.

Updater는 직접 호출하거나 여기에서처럼 갱신을 원하는 Element(여기서는 'msg' div)에 Element.load를 사용하여 접근하게 되는데 Element.load가 호출되었을 때 서버 측의 응답이 자동으로 Element의 innerHTML로 변경됩니다. 그리고 서버에서 응답을 처리할 URL과 인자값(여기서는 'name'필드의 값을 전달) 그리고 요철 처리 중간에 엘리먼트의 innerHTML에 표시할 메시지를 전달하고, Msg div(디폴트 값이 hidden으로 되어있음)가 보이게하면 됩니다.

물론 Ext 내 다른 부분들처럼 Updater에 많은 옵션들이 제공 되고 있으며 이것으로 여러 다양한 상황에서 Ajax요청을 필요에 맞는 방식으로 처리할수 있습니다. (Ajax 직접 접근은 Ext.Ajax 클래스를 살펴보시기 바랍니다) 하지만 여기에서는 기본적인 예제와 실행을 보여드렸습니다.

Ajax 퍼즐의 마지막 조각은 요청과 페이지로 보내는 응답을 담당하는 웹서버측의 처리부분입니다. 이 부분은 서버페이지, 서블릿, HTTP 핸들러, 웹서비스, 펄 혹은 CGI 스크립트 외에 웹 서버 측에서 HTTP 요청을 처리할 수 있는 어떤 기술도 될수 있겠습니다.

결국 이런 다양함으로 인해 표준적인 예제를 제공할 방법이 없습니다. 그래서 주로 사용되는 몇가지 언어로 예제를 만들었는데 독자에게 도움이 되었으면 합니다. (이 코드는 단순히 'name' 필드로 전달되는 입력 값을 다시 클라이언트 측에 'from Server: '에 붙여서 전달하고 'msg' div에 기록됩니다.) PHP 예제는 'ajax-example.php'로 다운로드를 제공하고 있지만 여러분의 서버에 맞는 코드로 수정해서 사용하시기 바랍니다.

ajax-example.php
<?php
if
(isset($_POST['name'])){
    echo 'from Server: '.$_POST['name'];
}
?>

실전에서는 Ajax 처리를 할때는 정확한 처리와 서버에서 오는 데이터 구조를 다루기 위해 땜방코드(--;)를 필요로 합니다. 사람들이 주로 사용하는 몇가지 포맷이 있는데(대부분 JSON or XML) Ext가 서버측 언어에 중립적인 것처럼 Ajax처리를 위해 많은 특정 언어 기반의 라이브러리가 Ext와 잘 연동됩니다.

페이지로 오는 데이터의 구조가 올바르면 서버의 어떠한 동작 방식에도 신경쓰지 않습니다.(^^) 서버측 프레임워크와 툴에 대한 부가적인 정보를 얻고 싶으면 우리의 platfrom-specific resources 목록을 살펴보시기 바랍니다.


- What's Next?


이제 Ext가 무엇이고 어떤 것을 제공하는지 맛을 살짝 보았습니다. 다음 단계로 진입하기 위해 도움이 될 많은 자료가 여러분을 기다라고 있습니다.


#Next Topic: Basic Login
Posted by 1010
반응형
일반적인 JavaScript Learning Guide

참고사이트

  1. Mozilla Developer Center: Core JavaScript 1.5 Reference Manual
  2. Yahoo UI개발자인 Douglas Crockford's JavaScript
  3. Yahoo Developer Network : YUI Theater  ( 더글라스 크록포드의 동영상 강의 수록)
  4. Peter-Paul Koch의 QuirksMode
  5. http://home.cogeco.ca/~ve3ll/jstutor0.htm

그외 볼만한 사이트(Dead Trees)

  1. JavaScript: The Definitive Guide by David Flanagan
  2. Pro JavaScript Techniques by John Resig
  3. Ajax and REST Recipes by Christian Gross
  4. ppk on JavaScript by Peter-Paul Koch
  5. Professional JavaScript for Web Developers by Nicholas C. Zakas
  6. Ajax Patterns and Best Practices by Christian Gross
  7. Dynamic HTML by Danny Goodman
  8. Head First Design Patterns by Freeman & Freeman

OO JavaScript 참조사이트

  1. How to achieve private, public, and privileged members in JavaScript, by Dustin Diaz.
    : Method scoping에 대한 좋은 설명
  2. OOP in JS, Part 1 : Public/Private Variables and Methods, by Gavin Kistner.
    : Scoping 및 prototyping에 대한 샘플
  3. A JavaScript Module Pattern, by Eric Miraglia in YUI Blog.
    : 더글라스 크록포드가 얘기한 module pattern에 대한 설명
  4. Again with the Module Pattern - reveal something to the world, by Christian Heilmann.
    : 모듈패턴
  5. JavaScript for Object-Oriented Programmers (Appendix B of the book AJAX in Action).

DOM




그외 기술


Yahoo! User Interface Library (YUI)

 

Ext JS 은 yui-ext에서 부터 시작되었다. 아래 사이트에서 YUI에 대해서 좀 봐두는것도 좋을지도..

  1. YUI Library
  2. ydn-javascript: Yahoo! User Interface Library Group
  3. YUI Blog

JSON 관련




Platform-Specific Resources


ExtJS를 서버사이드 프레임웍으로 사용한 녀석들.....

PHP

대표적인 샘플코드는 모두 PHP코드로 되어 있는 걸 보면  PHP에서 개발하기 가장 쉬운것 같음.
ExtJS 내장 PHP프레임웍 :  Qcodo Development Framework

Java


Direct Web Remoting (DWR) : http://getahead.org/dwr

.NET


  • AjaxPro 는 .Net 을 이용한 서버사이드 Ajax
  • Jayrock  :  .Net에 JSON / JSON-RPC 를 이용 
  • Json.NET  : .Net에서 JSON을 쓰게 만들어주는 라이브러리 (PHP의 toJSON()이나, Struts의 JSON과 같은건가 보다... ㅡ.,ㅡ; ) 

Ruby on Rails

Ext plugin - ROR는 내장 플러그인으로 작동하므로 gem을 이용해 받으면 되겠다...  (찾기가 더 힘드네.. ㅡ.,ㅡ;)

IBM Lotus Notes/Domino


IBM's Lotus Notes/Domino : IBM 머찌다라는 말만..



통합개발툴(IDE)

Eclipse Based IDEs

Eclipse 은 오픈소스 통합개발툴 (among other things!)이다. ExtJS개발을 위해 이클립스를 사용하기 위해서는 먼저 자바스크립트 사용할수 있는 플러그인을 설치해야 한다.
아래의 플러그인을 추천한다.

  • Aptana - JavaScript, HTML, CSS, PHP languages, FTP/SFTP 지원, RIA/Web2.0등 Ajax 관련 프로젝트에 적합 (느리다는 단점이 있음.. ㅠ.,ㅠ)
  • Spket - JavaScript, XUL, SVG, Laszlo, Silverlight,등 각 모듈 라이브러리 지원(http://blog.naver.com/techbug/150024518549 )
  • JSEclipse - JavaScript

위에 열거된 플러그 인들은 각자 자바스크립트 에디터를 포함하고 있다.  자바스크립트를 열때 "Open with"로 열어서 사용하도록...플러그인을 선택할때는 코드 assist를 지원하는지 확인해 봐야 할듯


Aptana + Spket + ExtJS(강추..)
  • Aptana다운로드 http://www.aptana.com/download_all.php
  • Aptana > Help > Software Updates > Find andInstall > Search for new features to install > New remote site..> "http://www.spket.com/update/"
  • Spket설치 ( Spket IDE Tutorial )
    1. Window > Preferences > Spket > JavaScript Profiles > New > "ExtJS"
    2. "ExtJS" 선택하고  "Add Library"에서 "ExtJS"선택
    3.  "ExtJS" 선택하고 "Add File", 에서 "./ext-2.0/source" 디렉토리에서 "ext.jsb"를 선택
    4. ExtJS profile을 디폴트로 선택
    5. Aptana 플러그인을 새 시작
    6. 새로운 JS파일을 만들면 ExtJS의 Code completion options를 볼수 있다.

AptanaIDE

  • Aptana는 상당히 매력적인 플러그인다. 대부분의 Ajax Library를 제공한다.




다양한 디버깅툴

Firebug (FF에서 강추)


Firebug는 Firefox에 애드온되어 작용하는데 웹페이지의 내용(CSS,HTML,Javscript등)을 실시간으로 볼수있는 상당히 매력적인 도구이다.


Screencasts


Tutorials


다른 브라우저에서 Firebug console을 이용하기

HTTP Trafic Viewer


피들러는 서버와 PC사이의 HTTP 트래픽 로그를 볼수 있는 디버깅 프록시이다. IE전용이나 Firefox의 proxy고급옵션에서 사용할수 있으며 자신이 원하는대로 필터링 하여 사용할수 있다.

MS Script Editor


IE Web Developper

IE WebDeveloper는 인터넷 익스플로러 애드온 프로그램이다.

Testing Data Generator

SQL,CSV,xml, excel등 테스트 데이타를 생성해준다.

http://www.benjaminkeen.com/software/data_generator/

YSlow

YSlow는  rules for high performance web sites를 기반으로 현재 페이지의 속도를 분석해준다. YSlow 는 Firefox 애드온 프로그램으로 인기가 있다.Firebug web development tool.

  • Performance report card
  • HTTP/HTML summary
  • List of components in the page
  • Tools including JSLint

http://developer.yahoo.com/yslow/

DebugBar - IE 플러그인 (강추)


  • DOM Inspector,
  • HTTP Inspector
  • Javascript Inspector and Javascript Console
  • HTML Validator
  • And many more features

http://www.debugbar.com/?langage=en

-->


출처 : http://jaywill.springnote.com/pages/1601738

Posted by 1010
반응형
오늘자 ExtJs 공식 블로그에 Intergrating Google Maps API With ExtJS 라는 글이 포스팅 되었다.

ExtJS 의 Panel 을 확장해서 만든 GMapPanel 을 이용한 샘플이 공개 되었는데 Google Maps API를 이용했다.
재미있는것은 Google 의 StreetView 도 Panel 를 확장해서 구현했단는 것.

사용자 삽입 이미지

지난달 초에 ExtJS 의 Web Desktop 샘플코드를 이용해서 NaverMap API 를 적용한 코드를 작성한 바 있는데 이를 소개할까 한다.

데모보기
사용자 삽입 이미지


Source Code (일부)
MyDesktop.MapWindow = Ext.extend(Ext.app.Module, {
id: 'map-win',
init: function(){
this.launcher = {
text: 'Where we are ?',
iconCls: 'icon-map',
handler: this.createWindow,
scope: this
}
},
createWindow: function(){
var desktop = this.app.getDesktop();
var win = desktop.getWindow('map-win');
var mapObj = null;

function centerMap(){
if (mapObj != null) {
mapObj.setCenterAndZoom(new NPoint(316350, 550250), 2);
}
}

if (!win) {
win = desktop.createWindow({
id: 'map-win',
title: 'Where we are?',
width: 740,
height: 480,
minHeight: 400,
minWidth: 500,
iconCls: 'icon-map',
shim: false,
animCollapse: false,
constrainHeader: true,
layout: 'fit',
tbar: ['서울특별시 성동구 성수1가2동 리버하우스', '->',
{
xtype: 'button',
iconCls: 'map-init',
text: '초기화',
handler: centerMap,
scope: this
}],
listeners: {
beforeshow: function(){
if (mapObj == null) { //최초 생성
mapObj = new NMap(this.body.dom);
mapObj.enableWheelZoom();
centerMap();
var zoom = new NZoomControl();
if (Ext.isIE6) {
var cm = new NMark(
new NPoint(316325, 550245),
new NIcon('images/here.gif',
new NSize(68, 50),
new NSize(34, 48)
)

)
} else {
var cm = new NMark(
new NPoint(316325, 550245),
new NIcon(
'images/here.png',
new NSize(68, 50),
new NSize(34, 48)
)

)
}
NEvent.addListener(cm, 'click', function(){
var w = new Ext.Window({
animateTarget: win.getEl(),
modal: true,
iconCls: 'icon-map',
title: '리버하우스 B동 207호',
html: '<img src="images/riverhouse.jpg">',
width: 360,
autoHeight: true,
resizable: false,
stateful: false
});
w.show();
});

cm.show();
zoom.setAlign("right");
zoom.setValign("top");
mapObj.addControl(zoom);
mapObj.addOverlay(cm);

} else { //생성된 적이 있다면!!
if (this.animateTarget == null) { //Close 상태
this.taskButton = desktop.taskbar.addTaskButton(this);
centerMap();
}
this.animateTarget = this.taskButton.el;
}

},
beforeclose: function(){
this.backupTarget = this.animateTarget;
this.animateTarget = null;
this.fireEvent('close', this); //taskButton remove
this.hide();
return false;
},
bodyresize: function(){
if (this.rendered && mapObj != null) {
mapObj.resize();
}
},
scope: win
}
});
}
win.show();
}
});

Web Desktop 의 작동방식은 바탕화면의 아이콘이나 시작버튼의 메뉴를 클릭하게 되면 Window 를 생성해서 화면에 보여주게 되는데 이때의 Window 는 별도의 객체에 의해서 생성된다. App 라는 Class 인데 Factory 이자 Status 를 관리하는 Manager 역할도 한다.
NaverMap과 연동하기 위한 코드는 코드상의 볼드 처리된 부분이며 주의할 점은

1. NaverMap API 는 한번만 초기화 되어야 한다.
Web Desktop 은 생성된 Window가 Close 될때 Destroy 하게 설계가 되어있다. 하지만 NaverMap 은 별도로 destroy를 할 수 있는 방법을 제공하지 않는다.
  1. NMap 을 전역으로 사용하던가
  2. mapWindow 의 멤버로 이용하려면 close 할때 window 를 destroy 하지 말고 hide 하는 방식을 취해야 한다.
상단의 코드는 후자의 방식을 택하고 있고, 파란색 beforeclose 리스너에서 hide 를 호출하고 Desktop App Manager 에서는 윈도우가 닫힌 것으로 인식하게 끔 close 이벤트를 발생시키고 있다.

2. Window resize 를 고려해야 한다.
우선 NMap 을 생성할 때 사이즈에 관한 인자를 주지 않으면 자동으로 컨테이너 사이즈로 생성됨을 확인하였다.
Window resize 이벤트가 발생할 때 NMap 의 인스턴스의 resize() 를 호출하야 한다. (소스코드 보라색)

그러나
사실 Web Desktop 에서 급히 쓰기해서 NaverMap 과의 연동부분이 샘플코드에 인라인으로 코딩이 되었지만 ExtJS 공식블로그에서 소개한 바와 같이 Panel을 확장해서 새로운 클래스로 만드는 편이 재사용을 위해 100만배는 좋다.
Posted by 1010
반응형
ExtJS의 기본 이해하기 ( Component Class의 inheritance 구현 및 계층 구조의 이해 )

  1. Ext.data.Connection = function(config){  
  2.     Ext.apply(this, config);  
  3.     this.addEvents(  
  4.         "beforerequest",  
  5.         "requestcomplete",  
  6.         "requestexception" 
  7.     );  
  8.     Ext.data.Connection.superclass.constructor.call(this);  
  9. };  


Ext.data.Connection 는 ExtJS의 Rmote server에 XHR Request를 위한 class이자 namespace 입니다.
사용자 삽입 이미지
ExtJS의 모든 Class는 Ext의 하위 패키지 그 안의 서브 클래스들로 구성되어 집니다.  이때 위 처럼 클래스들이 생성되어서 동작하기 위해서 기본적으로 하는 처리가 있습니다.


위의 소스를 간단하게 보겠습니다.
Ext.data.Connection 는 function 을 갖습니다. 첫번째 인자료 config 라는 Hash 형태의 오브젝트를 갖습니다.

Hash 형태의 오브젝트란? 
{ key : value }의 형태를 말하고 이해를 돕기 위해 Hash형 오브젝트라 칭합니다.
Hash형 오브젝트 타입은 value에는 다양한 type의 값이 올 수 있습니다.

이는 사용 시 new 연산자를 이용하여 인스턴스화 되게 됩니다.
즉 Ext.data.Connection은 function으로의 기능이 아닌 instance 화 되어 사용되게 됩니다.

그러면 인스턴스가 생성될 때 수행되는 컨텍스트를 봅니다.

Ext.apply(this, config); 는 아래의 Ext의 맴버로서 수행되어집니다.

  1. /**  
  2.  * Copies all the properties of config to obj.  
  3.  * @param {Object} obj The receiver of the properties  
  4.  * @param {Object} config The source of the properties  
  5.  * @param {Object} defaults A different object that will also be applied for default values  
  6.  * @return {Object} returns obj  
  7.  * @member Ext apply  
  8.  */ 
  9. Ext.apply = function(o, c, defaults){  
  10.     if(defaults){  
  11.         // no "this" reference for friendly out of scope calls  
  12.         Ext.apply(o, defaults);  
  13.     }  
  14.     if(o && c && typeof c == 'object'){  
  15.         for(var p in c){  
  16.             o[p] = c[p];  
  17.         }  
  18.     }  
  19.     return o;  
  20. };  


위의 apply에 의해서 this config로 넘겨준 값이 모두 overwrite 되게 됩니다. this가 가지고 있던 속성 및 메서드까지 모두 config가 가지고 있던 값으로 치환되어집니다.

이때 apply 에 첫번째 인자로 주는 config ExtJS에서는 해당 클래스가 갖는 속성의 의미와도 같습니다.

좀더 쉽게 풀이해서 쓴다면 ExtJS의 하나의 클래스가 인스턴스화 되어질 때 기본적으로 갖게 되는 속성 그리고 상속구조가 형성되면서 override 되는 속성과 메서드들의 기본 설정을 합니다.

좀더 쉬운 예를 들어보면 하나의 widget이 생성되어 브라우저에 띄울 때 그 widget의 기본 사이즈, 드래그 앤 드랍 등을 할 수 있는 설정을 이 config Hash 오브젝트로 넘겨주는 초기 설정값과도 같습니다.


  1. this.addEvents(  
  2.         "beforerequest",  
  3.         "requestcomplete",  
  4.         "requestexception" 
  5.     );  


이 코드는 이벤트 리스너를 설정하게 됩니다.  최근에 릴리즈한 자바스크립트 프레임웍에는 Custom Event가 모두 지원하고 있습니다. 

ExtJS에서도 이를 지원하는데요. 이는 Observable class에 있습니다. 
위의 코드는 이 Ext.data.Connection 이 인스턴스화 될 때 사용하게 될 기본적인 이벤트 리스너에 해당하는 것들입니다.

위에 잠깐 예시를 들었던 widget 에서는 기본적으로 widget을 움직일 수 있고 최소화 시킬 수 있는 기능을 기본적으로 갖게 됩니다.  경우에 따라서는 숨길 수 있는 기능이나 최대화 기능도 부여할 수 있습니다.  이처럼 this.addEvent를 통해서 Ext.data.Connection 이 갖는 기본적인 이벤트 리스너를 등록하게 됩니다.

XMLHttpRequest 를 통해서 서버측 데이터를 받아올 때 혹은 받을때 받고나서 등등 다양한 상황에 맞는 이벤트 리스너를 사용하기에 앞서 Connection 클래스가 기본적으로 갖게되는 이벤트 리스너를 설정해 주게 됩니다.  위의 경우 ‘beforerequest’, ‘requestcomplete’, ‘requestexception’ 3가지의 리스너를 설정하게 됩니다.

이렇게 설정된 리스너는 fireEvent 메서드 즉 핸들러를 수행하게 됩니다.

마지막 구문

Ext.data.Connection.superclass.constructor.call(this);

상당히 길게 나열된 구조입니다. ExtJS의 가장 중요한 부분이라고 해도 과언이 아닙니다. 어떻게 해서 저렇게 긴 메서드가 생성되었을까요 간단하게 풀이해서 보도록 합니다.
Ext.data.Connection 이것은 굳이 Ext.data.Connection 이라고 하지 않고 this라고 해도 무방했을텐데 왜 그랬는지 살짝 궁금해집니다.

this를 쓰지 않았던(?) 못했던(?) 이유... 2008.05.18 추가

more..



그 다음에 오는 superclass 는 단연 계층 구조에 있어서 최상위 클래스, 부모 클래스를 나타낼 텐데요.  superclass.constructor 입니다.  즉 superclass 가 아닌 superclass의 constructor를 나타냅니다.  이는 인스턴스화 되지 않는 부모 클래스의 생성자를 참조하고 있습니다.

그런데 과연 superclass 라는 것은 원래 있는 것인지? 아니면 ExtJS에서 기본적으로 제공하는 것인지 의문이 듭니다. 이는 Ext.extend 맴버에 의해서 Ext.data.Connection 에 부여됩니다.

Ext.extend(Ext.data.Connection, Ext.util.Observable, { … });

잠시 extend 메서드에 대한 설명을 간단하게 하고 넘어갑니다.
extend 메서드는 YUI의 구조와 동일합니다. 첫번째 인자로 넘어간 오브젝트에 superclass 속성을 부여하여 두번째 인자의 prototype을 superclass 가 레퍼런스하도록 합니다.

즉 Ext.data.Connection.superclass는 Ext.util.Observable.prototype을 레퍼런스하게 됩니다. 곧 Ext.util.Observable 의 constructor를 call 메서드를 통하여 호출하게 됩니다. 메서드를 Ext.data.Connection Scope에서 수행하게 됩니다.

이는 생성되면서 addEvent 를 통해서 생성된 이벤트 리스너의 동작을 켭니다. 이 말은 addEvent를 통해서 추가된 리스너들은 단지 ExtJS의 이벤트 class에 이벤트 이름만 등록하고 실제로 Ext.data.Connection 이 인스턴스화 될 때 비로소 리스너가 작동이 가능하게 됩니다.

언제나 그렇듯 말로만 보면 쉽게 이런 구조가 이해되지 않아서 간략하게 나마 그림으로 표현해 봅니다.

사용자 삽입 이미지


어차피 그림 조차도 설명이네요. ^^;

Posted by 1010