본문 바로가기

Sencha Touch 2

3일차 : Sencha Touch 2 Components 에 대한 이해!

센차2 블로그는, 제가 속한 CRA 에서 방학동안 진행하는 센차2 스터디 및 프로젝트에 도움을 주기위해 작성하게 됐습니다.. 

이 자리를 빌어, 방학 동안 프로젝트 하느라 수고할 

임 모양, 이 모군, 정 모군, 이 모양, 남 모양, 양 모양, 최 모군, 모두 모두 화이팅 이다!! ㅎㅎㅎ

(외부인들도 검색하면 보게 되는 블로그라서 full name 으로 쓰지는 않았업!ㅎ 원한다면 실명으로 수정해 주겠음 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ)



오늘 다룰 내용은 Components 에 대한 내용이다. (갑자기 반말로 가서 죄송.. 시간 관계상..ㅠㅠ)


Components 란 무엇인가?

센차 터치에서 사용자와 상호작용을 하는 눈에 보이는 클래스들을 components 라고 한다.


그래서 센차에서 모든 components 들은 Ext.Component 를 상속한 클래스 들이다.

(Ext.Components 에 대한 정보 : http://docs.sencha.com/touch/2-0/#!/api/Ext.Component)


Components 들이 할 수 있는 일들 (당장 몰라도 된다. 나중에 실습하고 익숙해지면 자동적으로 이해되는 부분이다.)

- Render themselves onto the page using a template

- Show and hide themselves at any time

- Center themselves on the screen

- Enable and disable themselves


위에서 언급한 것 외에도 추가적으로 할 수 있는 일들 (당장 몰라도 된다. 나중에 실습하고 익숙해지면 자동적으로 이해되는 부분이다.)

- Float above other components (windows, message boxes and overlays) : 다른 components 들 위에서 띄워서 보여질 수 있다.

- Change size and position on the screen with animation

- Dock other Components inside itself (useful for toolbars)

- Align to other components, allow themselves to be dragged around, make their content scrollable & more



Container 란 무엇인가?

위에서 언급한 모든 기능들을 가지면서도 동시에 다른 components 들을 그 안에 가질 수 있는 Components 이다.

* 거의 모든 app 은 단 하나의 top-level Container 를 가지는데 그 이름을 Viewport 라고 한다. 이 Viewport 는 전체 화면을 차지하고 있으며 그 안에는 여러러 child components 를 가지고 있다.


Containers 의 extra 기능 :

- Adding child Components at instantiation and run time. 처음 Container 를 만들면서 components 를 추가할 수 있고, run time 때 추가할 수도 있다.

- Removing child Components. 이미 자신이 가지고 있는 child components 를 지울 수 있다.

- Specifying a Layout : 레이아웃은 Container 가 가지는 child components 를 어떻게 배치할 것인지를 결정




Components 를 instantiating 시키자!

센차에서 다른 모든 클래스가 만들어지는 것과 마찬가지로 components 도 Ext.create 를 통해 만들어진다.

var panel = Ext.create('Ext.Panel', {
    html: 'This is my panel'
});


이렇게 하면 Ext.Panel 클래스에 대한 instance 를 만든다. 이 때, 만들면서 넘겨지는 속성은 'html 내용에 This is my panel 이라는 내용을 담자!' 라는 의미의 속성이 넘겨지게 되는 것이다. 그러나 create 한다고 바로 눈에 보이는 것은 아니다. 즉, instantiating 된다고 해서 바로 눈에 보이는 것은 아니다. 이는 중요한 속성인데, 왜냐하면 Components 들이 렌더링 되고 레이아웃이 잡혀서 자리가 잡히기 전에 여러 Components 들을 이동시킬 수 있기 때문이다. 이는 이미 rendering 된 Components 들을 움직이는 것 보다 더 빠르게 components 들을 움직일 수 있다.


위에서 만든 Panel 을 보여주기 위해서는 global Viewport 에 추가하면 된다.

Ext.Viewport.add(panel);


Panel 은 Container 에 한 종류이기 때문에 내부적으로 여러 아이템들을 담을 수 있고 레이아웃 배치를 줄 수 있다. 아래의 소스 코드를 참고하자. 


var panel = Ext.create('Ext.Panel', {
    layout: 'hbox',

    items: [
        {
            xtype: 'panel',
            flex: 1,
            html: 'Left Panel, 1/3rd of total size',
            style: 'background-color: #5E99CC;'
        },
        {
            xtype: 'panel',
            flex: 2,
            html: 'Right Panel, 2/3rds of total size',
            style: 'background-color: #759E60;'
        }
    ]
});

Ext.Viewport.add(panel);



여기서 중요한 것은 xtype 이다. xtype 은 Components 들을 (지금까지 설명한 Ext.create 없이, 그리고 class full name 을 적어줄 필요 없이) 손쉽게 만들 수 있는 방법들을 제공해 준다. 특히나 xtype 은, (다른 components 들을 child items 로 가질 수 있는) Container 에서 그 빛을 발하는데, 위의 예제에서 처럼 xtype: 'panel' 이라고 명시 해 놓으면, 맨 처음 만들어지는 panel 에 child components 로 panel 이 생성되게 된다. 

위의 예제에서는 총 세 개의 panel 이 있다. 가장 밖에 있는 panel, 그리고 그 panel 의 자식 components 로써 두 개의 panel 이 있다. 자식 panel 두 개는 xtype: 'panel' 을 통해 만들어 진 것을 알 수 있다. 

또 하나 주의 깊게 볼 것은 layout 인데, layout 은 Container 에 속한 아이템들을 어떤 형태로 배치할 것인가를 정의한다. 여기서 사용된 layout 은 'hbox' 이다. 즉, 자식 아이템들을 가로로 배치하게 되는 것이다. layout 에 대한 자세한 얘기는 다음 시간에 하겠다. (flex 는 전체 배율에서 얼마만큼을 차지할 것인가? 이다. 여기서는 hbox 를 사용했으므로 전체 가로 길이에서 하나의 panel 은 1/3 의 가로 길이를 차지하고 다른 하나의 panel 은 2/3 의 가로 길이를 차지한다)



Configuring Components! 속성 주기!!


처음 Components 들을 create 할 때 여러가지 설정 옵션 (config options) 들을 줄 수 있다. 


//we can configure the HTML when we instantiate the Component
var panel = Ext.create('Ext.Panel', {
    fullscreen: true,
    html: 'This is a Panel'
});

//we can update the HTML later using the setHtml method:
panel.setHtml('Some new HTML');

//we can retrieve the current HTML using the getHtml method:
Ext.Msg.alert(panel.getHtml()); //alerts "Some new HTML"


위의 코드의 경우, panel 을 만들 때, fullscreen 과 html 이라는 두 개의 설정을 뒀다. 


사용 가능한 설정이 어떤 것들이 있는 지 알고 싶다면 각 class 별 documentation 을 검색한 뒤 config options 에 해당하는 부분을 보면 된다. 예를 들어 toolbar 를 만들면서 속성을 주고 싶은데 어떠한 속성들이 있는지를 알고 싶다면 아래처럼 toolbar 를 검색한 뒤, config options 부분을 참고해서 필요한 속성을 주면 된다.





그리고 위이 코드에서도 보는 것 처럼, 각 config 는 모두 setter 과 getter 를 가진다.



Xtype 사용하기


앞에서 설명한 것처럼, xtype 은 Components 들을 쉽게 만드는 방법이다.


Ext.create('Ext.Container', {
    fullscreen: true,
    layout: 'fit',

    items: [
        {
            xtype: 'panel',
            html: 'This panel is created by xtype'
        },
        {
            xtype: 'toolbar',
            title: 'So is the toolbar',
            docked: 'top'
        }
    ]
});


간편하게 panel 과 toolbar 를 만드는 것을 볼 수 있다.



xtypes list

xtype                   Class
-----------------       ---------------------
actionsheet             Ext.ActionSheet
audio                   Ext.Audio
button                  Ext.Button
component               Ext.Component
container               Ext.Container
image                   Ext.Img
label                   Ext.Label
loadmask                Ext.LoadMask
map                     Ext.Map
mask                    Ext.Mask
media                   Ext.Media
panel                   Ext.Panel
segmentedbutton         Ext.SegmentedButton
sheet                   Ext.Sheet
spacer                  Ext.Spacer
title                   Ext.Title
titlebar                Ext.TitleBar
toolbar                 Ext.Toolbar
video                   Ext.Video
carousel                Ext.carousel.Carousel
carouselindicator       Ext.carousel.Indicator
navigationview          Ext.navigation.View
datepicker              Ext.picker.Date
picker                  Ext.picker.Picker
pickerslot              Ext.picker.Slot
slider                  Ext.slider.Slider
thumb                   Ext.slider.Thumb
tabbar                  Ext.tab.Bar
tabpanel                Ext.tab.Panel
tab                     Ext.tab.Tab
viewport                Ext.viewport.Default

DataView Components
---------------------------------------------
dataview                Ext.dataview.DataView
list                    Ext.dataview.List
listitemheader          Ext.dataview.ListItemHeader
nestedlist              Ext.dataview.NestedList
dataitem                Ext.dataview.component.DataItem

Form Components
---------------------------------------------
checkboxfield           Ext.field.Checkbox
datepickerfield         Ext.field.DatePicker
emailfield              Ext.field.Email
field                   Ext.field.Field
hiddenfield             Ext.field.Hidden
input                   Ext.field.Input
numberfield             Ext.field.Number
passwordfield           Ext.field.Password
radiofield              Ext.field.Radio
searchfield             Ext.field.Search
selectfield             Ext.field.Select
sliderfield             Ext.field.Slider
spinnerfield            Ext.field.Spinner
textfield               Ext.field.Text
textareafield           Ext.field.TextArea
textareainput           Ext.field.TextAreaInput
togglefield             Ext.field.Toggle
urlfield                Ext.field.Url
fieldset                Ext.form.FieldSet
formpanel               Ext.form.Panel

http://docs.sencha.com/touch/2-0/#!/api/Ext.Component   <-- 여기서도 확인할 수 있다. 왼쪽 링크는 component 로 검색해서 나온 것이다.



Container 에 components 를 추가하기

Container 에 Components 를 추가하는 방법은 두 가지이다.

앞에서 본 것 처럼 처음 create 할 때 미리 명시하는 방법이고, 아니면 add 메소드를 통해 panel 에 추가하는 방법이다.


//this is the Panel we'll be adding below
var aboutPanel = Ext.create('Ext.Panel', {
    html: 'About this app'
});

//this is the Panel we'll be adding to
var mainPanel = Ext.create('Ext.Panel', {
    fullscreen: true,

    layout: 'hbox',
    defaults: {
        flex: 1
    },

    items: {
        html: 'First Panel',
        style: 'background-color: #5E99CC;'
    }
});

//now we add the first panel inside the second
mainPanel.add(aboutPanel);


위의 코드는 두 가지 방식 모두를 보여준다. defauts 는 해당 Panel 에 child components 로 들어올 모든 items 에 대해서 공통적으로 적용될 사항을 명시 해 놓은 것이다. 위의 코드는 모든 child items 들은 flex 는 1 값을 가지도록 하겠다라는 의미이다.


추가한 아이템을 삭제하려면 아래와 같이 실행하면 된다.

mainPanel.remove(aboutPanel);





Components 를 보이게도 하기 사라지게도 하려면?

각 components 들을 보이게도 할 수 있고 안 보이게도 할 수 있다. 


아래 코드를 참고!!


mainPanel.hide();

mainPanel.show();


둘 다 자기 자신 뿐 만 아니라 자기 자신이 포함하는 items 들 까지도 모두 보이게도 하고 안보이게도 한다.




이벤트??!!

모든 components 들은 자기 자신과 관련된 events 들이 있고 그 events 들이 발생할 때 마다 해당 events 들을 들을 수 있다. 

예를 들어 Text field 에 글이 써 질 때 마다, change 라는 events 들이 발생하게 되는데, 해당 events 가 발생할 때 마다 listen 하는 방법은 아래와 같다. 


Ext.create('Ext.form.Text', {
    label: 'Name',
    listeners: {
        change: function(field, newValue, oldValue) {
            myStore.filter('name', newValue);
        }
    }
});


위 코드에서는 change event 가 발생할 때 마다 myStore 이라는 이름을 가지는 store 에서 name 이라는 속성의 값이, 지금까지 입력한 내용에 해당하는 값을 가지는 것만 필터하라는 의미이다. (지금 두 줄에 대한 내용은 지금 몰라도 괜찮다. 토닥토닥. 아직 안 배웠으니까 모르는게 당연하다.)







Docking : Container 에서 components 를 고정시키기!


센차는 또한 Container 의 고정된 위치에 아이템을 둘 수 도 있다. 


var mainPanel = Ext.create('Ext.Panel', {
    fullscreen: true,

    layout: 'hbox',

    items: [
	{
        	html: 'First Panel',
	        style: 'background-color: #5E99CC;'
	},
	{
		docked: 'top',
		xtype: 'titlebar',
		title: 'My app'
	}
    ]
});


위에 대한 결과 화면은 아래와 같다.





Components 를 파괴하기??!!

휴대폰에서 돌아가는 app 이다 보니 메모리 관리가 중요한 이슈가 된다. 그러므로 좀 더 효율적이고 최적화된 app 을 만들기 원한다면 메모리 관리를 해줘야 하고, 그 말은 instatiating 된 components 들 중에 자주 사용하지 않는 것들은 적절히 메모리에서 제거해줘야 한다. Components 를 메모리에서 제거하는 방법은 destroy 메소드를 호출하면 된다.


mainPanel.destroy();


이렇게 호출하게 되면 자기 자신은 물론, 자기 자신과 관련된 이벤트, 그리고 자기 자신이 가지고 있는 모든 items 까지도 recursive 하게 destroy 를 호출해서 제거해 준다.