BLOG ARTICLE sencha touch | 1 ARTICLE FOUND

  1. 2011.12.08 Sencha Touch 기본 강좌 - 마이크로 소프트웨어 (2)

출처 : http://www.imaso.co.kr/?doc=bbs/gnuboard.php&bo_table=article&sselect=wr_subject%7Cwr_content&stext=sencha&soperator=0&page=1&wr_id=36789

본격적으로 Sencha Touch 개발을 준비해 보자.

Sencha Touch 준비과정
Sencha Touch 준비과정은 간단하다. Sencha Touch가 제공해 주는 sencha-touch.js 파일과 sencha-touch.css 파일을 포함시키면 준비는 끝이다(sencha-touch-debug.js와 sencha-touch-debug.css는 개발 용도로 소스코드가 분석하기 편하게 돼 있는 파일이다).

먼저 http://www.sencha.com/products/touch/download. php에서 다운로드하자.


<화면 1> Sencha.com에서 다운받을 수 있다.

받은 sencha-touch-1.0.1a.zip(2011. 1. 2 기준) 파일을 풀어보면 <화면 2>와 같은 많은 파일들을 볼 수 있다.


<화면 2> Sencha Touch 구성파일들

Sencha Touch의 경쟁 제품인 jQuery Mobile(아직 알파 버전)이 “Hello World” 예제조차 제공해 주지 않는 것에 비하면 Sencha Touch의 구성은 종합선물세트처럼 반갑게 느껴진다. 자주 사용하게 될 폴더는 API 문서 폴더(/docs)와 예제 폴더(/examples)를 주로 사용하게 된다. 먼저 index.html 파일을 만들어 sencha-touch-debug.js 파일과 sencha-touch-debug.css 파일을 포함시키자. 이로써 간단하게 Sencha Touch 개발 준비가 끝난다.

<리스트 1> 가장 먼저 실행될 index.html 파일

1 <html>
2 <head>
3 <title>Sencha</title>
4 <meta charset="utf-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <link rel="stylesheet" href="sencha-touch-debug.css" type="text/css">
7 <script type="text/javascript" src="sencha-touch-debug.js"></script>
8 </head>
9 <body>
10 </body>
11 </html>

Sencha Touch 기본 설정
실제 코드는 자바스크립트로 작성하게 되며, 자바스크립트를 index.html 안에 기술해도 상관 없으나 자바스크립트 내용이 많아 별도 index.js 파일을 만들어 기술하기로 한다.

<리스트 2> 기본 설정을 위한 index.js 파일 추가

1 <html>
2 <head>
3 <title>Sencha</title>
4 <meta name="viewport" content="width=device-width, initial-scale=1.0">
5 <link rel="stylesheet" href="sencha-touch-debug.css" type="text/css">
6 <script type="text/javascript" src="sencha-touch-debug.js"></script>
7 <script type="text/javascript" src="intex.js"></script>
8 </head>

index.js를 추가하고 viewport 메타 태그를 이용해 화면 크기를 조절한다(viewport 메타 태그는 모바일 웹킷 기반 브라우저(Android,iPhone)의 화면 크기를 기기의 해상도와 상관없이 설정할 수 있다).

<리스트 3> Ext.setup을 통해 기본 설정

index.js
1 Ext.setup({
2   tableStartupScreen:'tstart.png',   // 타블렛 시작 이미지
3   phoneStartupScreen:'pstart.png',   // 폰 시작 이미지
4   icon:'icon.png',   // 바탕화면 아이콘
5   glossOnIcon:false
6 });

Sencha Touch의 Ext class의 setup이라는 메소드를 통해 다양한 기본 설정들을 할 수 있다. 2번 라인부터 3번 라인은 페이지의 로고와 같은 이미지를 설정하는 파라미터다. 4번 라인은 홈 화면에 추가할 때 사용될 이미지를 설정하는 것이다. 5번 라인은 4번 라인의 이미지에 gloss on icon 효과를 줄 지를 설정하는 파라미터다.

gloss on icon 효과란 애플에서 제공하는 기본적인 아이콘 효과를 얘기한다. <화면 3>의 아이콘을 보면 그 차이를 확실히 알 수 있다. 제공하려는 아이콘에 gloss on icon 효과를 적용하고 싶지 않을 때 우리는 false로 효과를 제어하면 된다.


<화면 3> gloss on icon 효과 적용 전과 후

<리스트 4> “Hello Sencha” 출력

index.js1 Ext.setup({
2    tabletStartupScreen: 'tstart.png',
3    phoneStartupScreen: 'pstart.png',
4    icon: 'icon.png',
5    glossOnIcon: false,
6    onReady: function() {
7       new Ext.Panel({
8          fullscreen: true,
9          layout: 'fit',
10         items: [
11            {html: "Hello Sencha"}
12         ]
13      });
14    }
15 });

기본적인 설정이 끝났으면 “Hello Sencha”를 출력해 보자.

6번 라인의 onReady는 DOM이 준비된 상태일 때 실행되는 함수를 정의할 수 있다. 우리가 호출한 페이지가 시작될 때 가장 먼저 실행되는 곳이라 보면 된다.

Sencha Touch는 HTML 개발 방식과 다르게 컴포넌트 기반으로 구성된다. 자바의 GWT처럼 Panel을 붙이고 그 위에 또 Panel을 붙여 구성한다고 보면 된다. 가장 기본적인 Ext.Panel을 사용했다. fullscreen을 이용해 width와 height를 100%로 설정한다. layout은 auto, card, fit, hbox, vbox 등이 있는데 여기서는 fit으로 처리했다. 이렇게 layout을 설정하고 나면 item으로 내용을 채워줘야 한다. 여기서는 layout:fit과 같이 하나의 item으로 html 속성을 이용해 “Hello Sencha”를 출력한다.


<화면 4> "Hello Sencha" 출력화면

Hello Sencha가 무사히 나왔다면 이제 복합적인 웹앱을 만들어 보자. 예제에서는 카페 웹앱을 만들어 보겠다. 리스트에는 음료와 케이크가 나오고 맵에는 해당 카페의 위치가 표시되게끔 하려고 한다.

먼저 상단에 탭 바를 하나 만든다. 물론 탭 바도 Sencha Touch가 제공하는 Ext.TabPanel을 사용하므로 별도 디자인을 할 필요는 없다.

1) ui : ui에 대한 일종의 테마를 선택하는 속성이다. 기본은 ‘dark’로 설정돼 있다. 
2) tabBarDock : 탭 바를 어디에 두는지 정하는 속성이다. ‘top’ 또는 ‘bottom’으로 탭 바의 위치를 결정한다.
3) cardSwitchAnimation : 페이지 전환 시 줄 애니메이션을 정하는 속성이다. 기본적으로 Ext.anims에서 사용할 수 있는 값을 설정할 수 있다. default로 ‘slide’가 돼 있고, ‘false’ 또는 ‘fade’, ‘slide’, ‘flip’, ‘cube’, ‘pop’, ‘wipe’ 등이 있다.

New Ext.TabPanel을 통해 생성하고 탭 패널의 속성을 <리스트 5>와 같이 설정한다.

<리스트 5> 탭 바 추가

index.js 1 Ext.setup({
 2  tabletStartupScreen: 'tstart.png',
 3  phoneStartupScreen: 'pstart.png',
 4  icon: 'icon.png',
 5  glossOnIcon: false,
 6  onReady: function() {
 7     var panel;
 8                    
 9     panel = new Ext.TabPanel({
10         fullscreen: true,
11         cardSwitchAnimation: 'slide',
12         ui: 'dark',
13         items: [
14            {title: "List"}, {title: "Map"}
15         ]
16      });
17   }
18 });


<화면 5> 바에 List, Map 메뉴 생성

기본적인 설정을 해줬으면 ‘List’, ‘Map’ Panel의 내용을 작성한다. 각 Panel을 담을 변수 listPanel과 mapPanel를 선언하자(<리스트 6>의 7번 라인).

<리스트 6> 탭 바 메뉴 선택 시 출력될 패널 추가

index.js1 Ext.setup({
2    tabletStartupScreen: 'tstart.png',
3    phoneStartupScreen: 'pstart.png',
4    icon: 'icon.png',
5    glossOnIcon: false,
6    onReady: function() {
7       var panel, listPanel, mapPanel;
8                     
9       listPanel = {
10          title: "List",
11          html: "리스트 페이지"
12       };
13                     
14       mapPanel = {
15          title: "Map",
16          html: "맵 페이지"
17       };
18                  
19       panel = new Ext.TabPanel({
20          fullscreen: true,
21          cardSwitchAnimation: 'slide',
22          ui: 'dark',
23          items: [
24             listPanel, mapPanel
25          ]
26       });
27    }
28 });

Sencha Touch에서는 대부분의 값을 JSON 형식으로 전달한다. 아주 간단하면서 간편한 문법이나 처음 접하는 분에게는 낯설게 느껴져 Sencha Touch 전체가 어려워 보이게 마련이다. JSON (JavaScript Object Notation)은 자료를 주고 받을 때 표현하는 방법이다(이러한 것으로 XML도 있으나 어렵고 사용법이 불편해 간단한 데이터를 표현하는 곳에는 적합하지 않다). JSON은 Key와 Value 구조를 갖고 있다. 다음 예제를 보면 쉽게 이해할 수 있을 것이다.

var car_name = ‘SONATA’;
var car_color = [‘red’, ‘blue’];
var car_price_red = 100;
var car_price_blue = 200;

차량 색상에 따른 가격 차이를 표현하는데 쉽지 않다. JSON의 표현방식으로 표현하면 다음과 같다.

var car = {name : ‘SONATA’ , color : { red : 100, blue : 200 } }

이와 같이 JSON으로 표현하면 복잡한 데이터도 간단히 표현할 수 있다. 데이터 호출은 다음과 같이 할 수 있다.

alert( car.name );   // ‘SOANATA’ 출력
alert( car.color.red );   // 100 출력


<화면 6> 탭 바 메뉴 선택시 화면 출력

리스트는 Ext.NestedList를 사용한다. 리스트로 사용할 데이터를 따로 자바스크립트 파일로 만들어 분리해 놓고 <리스트 7>과 같이 내용을 채워 넣는다.

 <리스트 7> Ext.NestedList에 추가할 list.js

list.js1 var data = {
2    text: '카페',
3    items: [{
4       text: '음료',
5       items: [{
6          text: '물',
7          items: [{
8             text: '탄산수',
9             leaf: true
10          },{
11             text: '생수',
12             leaf: true
13          }]
14       },{
15          text: '아메리카노',
16          leaf: true
17       },{
18          text: '에스프레소',
19          leaf: true
20       },{
21          text: '카라멜 마끼아또',
22          leaf: true
23       }]
24    },{
25       text: '케이크',
26       items: [{
27          text: '치즈케이크',
28          leaf: true
29       },{
30          text: '생크림케이크',
31          leaf: true
32       }]
33    }]
34 };
35  
36 Ext.regModel('ListItem', {
37    fields: [{name: 'text', type: 'string'}]
38 });
39  
40 var store = new Ext.data.TreeStore({
41    model: 'ListItem',
42    root: data,
43    proxy: {
44       type: 'ajax',
45       reader: {
46          type: 'tree',
47          root: 'items'
48       }
49    }
50 });

data 변수에 리스트에 추가할 메뉴들을 담았다. leaf:true의 의미는 더 이상의 자식 노드가 없다는 것이다. 이렇게 담았다고 바로 사용할 수 있는 것은 아니다. Ext.regModel을 이용해 정의해야만 Ext.data.TreeStore에서 가져다 사용할 수 있다.

우리가 데이터를 사용할 때 사용할 수 있는 메소드 중 여기서는 TreeStore를 사용했다. model 속성에 Ext.regModel에서 정의한 데이터 패키지를 지정해 주고 root 속성에 data 변수를 대입한다.

proxy 속성에서는 type을 ajax로 정하고 reader 속성의 type을 tree 구조로, root는 items로 정했다. 만약 json으로 한다면 proxy에 url 속성을 추가하고 reader.type:을 json으로 설정한 후 root를 해당 json에 맞게 설정해 사용할 수 있다.

 <리스트 8> json 사용 예

var myStore = new Ext.data.Store({
   model: 'User',
   proxy: {
      type: 'ajax',
      url: '/users.json',
      reader: {
         type: 'json',
         root: 'users'
      }
   }
   autoLoad: true
})

이렇게 만든 리스트(list.js)를 index.html에 추가한다.

 <리스트 9> list.js 파일을 index.html 파일에 추가

1 <!DOCTYPE html>  
2 <html>
3 <head>
4 <title>Sencha</title>
5 <meta charset="utf-8">
6 <meta name="viewport"content="width=device-width, initial-scale=1.0">
7 <link rel="stylesheet"href="sencha-touch-debug.css"type= "text/css">
8 <script type="text/javascript"src="sencha-touch-debug.js"></script>
9 <script type="text/javascript"src="index.js"></script>
10 <script type="text/javascript"src="list.js"></script>
11 </head>
12 <body>
13 </body>
14 </html>

list.js를 index.html에 포함시켰으면 index.js 파일에 추가하는 작업을 시작하자.

 <리스트 10> list.js에서 정의한 store를 listPanel에 추가

1 Ext.setup({
2    tabletStartupScreen: 'tstart.png',
3    phoneStartupScreen: 'pstart.png',
4    icon: 'icon.png',
5    glossOnIcon: false,
6    onReady: function() {
7       var panel, listPanel, mapPanel;
8                      
9       listPanel = new Ext.NestedList({
10          fullscreen: true,
11          title: 'List',
12          displayField: 'text',
13          store: store
14       });
15                      
16       mapPanel = {
17          title: "Map",
18          html: "맵 페이지"
19       };
20                      
21       panel = new Ext.TabPanel({
22          fullscreen: true,
23          cardSwitchAnimation: 'slide',
24          ui: 'dark',
25          items: [
26             listPanel, mapPanel
27          ]
28       });
29    }
30 });

listPanel을 Ext.NestedList 패널로 변경하고 몇 가지 속성을 채운다. store 속성에는 앞서 list.js에서 작성한 store를 추가한다.


<화면 7> Ext.NestedList 적용 모습

Ext.NestedList를 사용했기 때문에 <Back> 버튼이 자동으로 생성된 것을 볼 수 있다. 리스트를 만들어 봤으니 해당되는 리스트의 화면도 만들어 보자.

 <리스트 11> list.js에서 특정 문자열을 가져와 화면에 출력

index.js1 Ext.setup({
2    tabletStartupScreen: 'tstart.png',
3    phoneStartupScreen: 'pstart.png',
4    icon: 'icon.png',
5    glossOnIcon: false,
6    onReady: function() {
7       var panel, listPanel, mapPanel;
8                      
9       listPanel = new Ext.NestedList({
10          fullscreen: true,
11          title: 'List',
12          displayField: 'text',
13          store: store,
14          getDetailCard: function(item, parent) {
15             detailCard = new Ext.Panel({
16                tpl: "{text}"
17             });
18             detailCard.update(item.attributes.record.data);
19                return detailCard;
20          }
21       });        
22                      
23       mapPanel = {
24          title: "Map",
25          html: "맵 페이지"
26       };
27                     
28       panel = new Ext.TabPanel({
29          fullscreen: true,
30          cardSwitchAnimation: 'slide',
31          ui: 'dark',
32          items: [
33             listPanel, mapPanel
34          ]
35       });
36    }
37 });

우리가 사용했던 Ext.NestedList에 list.js에 있는 특정 값을 가져와 Ext.Panel로 만들어 찍어 주기 위해 getDetailCard 속성과 함수를 추가했다. 14번 라인에서 Ext.NestedList의 값을 가져와 detailCard에 새 Panel을 생성, 18번 라인을 통해 업데이트시킨 후 반환함으로써 화면에 보여진다.

이렇게 Sencha Touch를 이용해 리스트를 만들고 화면에 보여주는 다양한 방식 중에 한 방식을 선택해 코딩까지 해봤다. 우리가 리스트를 거쳐 ‘카라멜 마끼아또’를 선택하면 {text}를 가져와 화면에 뿌려준다. 이 부분에 ajax를 활용해서 더 다양한 화면구성이 가능하다.


<화면 8> 리스트 선택 후 화면 출력

이상 설치법과 NestedList를 이용한 화면 구성을 알아봤다. 다음 호에서는 이번 호에 이어 구글 맵 API를 이용해 탭 바 메뉴 Map을 통해 카페 위치를 지도에 표시해 보고, xtype 객체를 사용하지 않고 익숙한 HTML과 Ajax를 이용해 구성해 보자.

'♨ Framework > Sencha-Touch' 카테고리의 다른 글

Sencha Touch 기본 강좌 - 마이크로 소프트웨어  (2) 2011.12.08
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST
  1. 꼬렙 2011.12.09 21:14 신고  댓글주소  수정/삭제  댓글쓰기

    김 주임~
    스마트폰 공부한다고 고생이 많소 ㅋㅋㅋㅋㅋ
    나중에 나도 이쪽으로 업무하게 되면 많은 조언 부탁하오~