Intro
지금까지 우리는 Components 들에 의해 표현 되는 View 들과, app 에서 View 에 의해 표현될 모든 데이터들의 형식을 나타내는 Model 들 을 배웠다. 이제 하나가 남았는데, 바로 Controller 이다.
지금까지의 과제에서는 우리가 새로운 View 추가를 했지만, 실제로는 Model 과 Controller 를 View 에서 분리시킬 수 있다.
HW7 의 해답을 보면서 어떻게 분리 될 수 있는지 확인해 보자.
먼저 HW7 의 실행화면은 아래와 같다. Ext.data.List 를 활용해서 서버로 부터 보내주는 데이터를 리스트 형태로 나타내고, 그 중에 아이템을 하나 선택하면 나이를 출력해 주는 프로그램이었다.
위의 app 에서 서버 역할을 하는 파일은 persons.jsp 이다. 아래와 같이 생겼다. 사진 밑에 파일 첨부했다.
해당 데이터를 출력하는 자바스크립트 파일을 ModelPanel.js 이런식으로 만들었고, 아래와 같은 내용을 담고 있다.
Ext.define('User', { extend: 'Ext.data.Model', config: { fields: [ {name: 'id', type: 'int'}, {name: 'name', type: 'string'}, {name: 'age', type: 'int'}, {name: 'gender', type: 'string'} ], } }); Ext.define("Sample.view.ModelPanel", { extend: 'Ext.Panel', xtype: 'modelpanel', requires: [ 'Ext.data.Store', 'Ext.dataview.List' ], config:{ title: 'model', iconCls: 'compose', layout: 'fit', items: [ { xtype: 'list', id: 'list', itemTpl: '{id}{name} : {age}', listeners: { itemtap: function(list, index, target, record){ Ext.Msg.alert("AGE", record.get("age")); } }, store: Ext.create('Ext.data.Store', { model: 'User', autoLoad:true, proxy: { type: 'ajax', url : './data/persons.jsp', reader: { type: 'json', rootProperty: 'persons' } }, listeners: { load: function(store, records, successful){ debugger; } } }) } ] }, });
위의 파일은 app.js 와 main.js 에 각각 아래와 같이 포함되어 있다.
- app.js 일부 캡쳐 사진.
- main.js 일부 캡쳐 사진
1. Model 분리하기
자, 이제 설명하기 위한 모든 준비는 끝이 났다. 이제 우리가 할 것은 ModelPanel.js 를 MVC 개념으로 분리시킬 것이다.
먼저 Model 을 분리시키자. 현재 ModelPanel.js 에서는 (User 라는 이름의) Model 과 (ModelPanel 이라는 이름의) View 가 따로 정의 되 있다. Model 을 User.js 라는 이름으로 자바스크립트 파일을 만들고 app.model 폴더 밑에 두자.
Ext.define('User', { extend: 'Ext.data.Model', config: { fields: [ {name: 'id', type: 'int'}, {name: 'name', type: 'string'}, {name: 'age', type: 'int'}, {name: 'gender', type: 'string'} ], } });
아래는 폴더 위치이다.
그리고 등록된 Model 은 app.js 에 반드시 추가를 해줘야 한다. 그래야 처음 app 이 시작할 때 해당 Model 을 load 할 수 있다. 그래서 아래는 수정된 app.js 코드이다.
2. Store 분리하기
MVC 패턴이라고 하면 보통 Model View Controller 로 분리시키는데, 센차에서는 추가적으로 Store 이라는 것을 분리시킨다.
store 에 적혀져 있는 부분을 따로 빼내는 것이다. 아래 코드는 store 을 따로 빼내서 store 디렉토리 안에 저장한 Users.js 파일의 모습이다.
Ext.define('Sample.store.Users', { extend: 'Ext.data.Store', config: { model: 'Sample.model.User', autoLoad:true, proxy: { type: 'ajax', url : './data/persons.jsp', reader: { type: 'json', rootProperty: 'persons' } }, } });
그리고 app.js 에 아래와 같이 추가해 주자.
이렇게 함으로써 드디어 model view store 까지 분리를 했다. 지금까지의 작업을 했을 때 ModelPanel 의 모습을 아래와 같다.
Ext.define("Sample.view.ModelPanel", { extend: 'Ext.Panel', xtype: 'modelpanel', requires: [ 'Ext.data.Store', 'Ext.dataview.List' ], config:{ title: 'model', iconCls: 'compose', layout: 'fit', items: [ { xtype: 'list', id: 'list', itemTpl: '{id}{name} : {age}', listeners: { itemtap: function(list, index, target, record){ Ext.Msg.alert("AGE", record.get("age")); } }, store: 'Users' } ] }, });
3. Controller 분리하기
마지막으로 controller 를 만들어 보자. controller 는 view 에서 발생한 이벤트들을 처리를 해준다!!!
이게 중요한 것인데, 다시 한번 강조하면, controller view, 즉 components 들에서 발생한 이벤트들을 catch 하고 그 이벤트들을 처리하는 역할을 한다.!!
controller 에서 특히 중요한 두 가지가 있는데 하나는 refs 고 하나는 control 이다.
3.1 refs
이미 존재하는 Components 를 가리킨다. Components 를 찾는 방법은 ComponentQuery 를 사용해서 찾는다. ComponentQuery 를 어떻게 사용해야 하는지는 API 를 검색해서 공부해야 한다. refs 를 어떻게 사용하는지는 아래의 코드를 보자.
Ext.define('MyApp.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
nav: '#mainNav'
}
},
addLogoutButton: function() {
this.getNav().add({
text: 'Logout'
});
}
});
여기서 nav 는 ID 가 mainNav 인 Component 를 가리키게 된다. addLogoutButton 메소드는 controller 를 새로 정의하면서 프로그래머가 추가해준 메소드인데, 중요한 것은 이 내부에서 어떻게 nav 를 access 할 수 있는가? 이다.
코드에서 보는 것 처럼, this.getNav() 를 호출하면 해당 component 를 얻어올 수 있다.
3.2 control
control 은 아까 위에서 정의한 refs 를 통해 얻은 component 들에 대해서 이벤트가 발생했을 때, 그 이벤트를 핸들링 하는 함수를 정의하는 곳이다. 아래 예제 코드를 보자.
Ext.define('MyApp.controller.Main', {
extend: 'Ext.app.Controller',
config: {
control: {
loginButton: {
tap: 'doLogin'
},
'button[action=logout]': {
tap: 'doLogout'
}
},
refs: {
loginButton: 'button[action=login]'
}
},
doLogin: function() {
//called whenever the Login button is tapped
},
doLogout: function() {
//called whenever any Button with action=logout is tapped
}
});
refs 에서 xtype 이 button 이면서 propety 로 action 을 가지며, 그 값이 login 인 component 를 가져온다. 그리고 그 reference 는 loginButton 이 가리키도록 한다.
control 에서 loginButton 에 tap 이벤트가 발생하면 doLogin 메소드를 호출하라고 정한다.
doLogin 메소드는 아래에서 따로 구현이 되야 하는 것이다.
자! 그럼 이제 우리 코드에 controller 를 적용해보자.
현재 상태는 list 에서 발생하는 itemtap 에 대한 이벤트를 다루고 있기 때문에, 일단 controller 에서는 list 에 접근할 수 있도록 해야 한다. list 는 xtype 이 modelpanel 인 component 의 내부 아이템으로 있기 때문에 (공부하면서 확인할 수 있겠지만) 'modelpanel list' 이렇게 접근할 수 있다.
아래 코드를 보자.
Ext.define('Sample.controller.Users', { extend: 'Ext.app.Controller', config: { refs: { userList: 'modelpanel list' }, control: { userList: { itemtap: 'onListItemTap' } } }, onListItemTap: function(list, index, target, record){ debugger; Ext.Msg.alert("AGE", record.get("age")); } });
코드에서 봐서 알 수 있듯이, userList 가 list 에 access 할 수 잇도록 refs 에 정의한 뒤, itemtap 이 발생했을 때, onListItemTap 을 호출할 수 있도록 control 에서 정의해 놓았다.
그리고 onListItemTap 이라는 메소드를 통해 함수를 호출하고 있음을 알 수 있다.
Controller 를 정의할 때는 Ext.app.Controller 를 상속해야 하고, 상속한 클래스의 이름을 정의해야 하는데, 여기서는 이름을 Sample.controller.Users 라고 줬다.
해당 코드를 담고 있는 자바스크립트의 파일 이름은 User.js 이며, 이 파일은 controller 폴더 밑에 있다.
그리고 마지막으로 app.js 에 controllers 를 추가해줘야 한다.
4. MVC application 을 만들때
MVC 형태로 등록을 할 때 보통 아래와 같이 등록을 한다.
Ext.application({
name: 'MyApp',
views: ['Login'],
models: ['User'],
controllers: ['Users'],
stores: ['Products'],
profiles: ['Phone', 'Tablet']
});
이렇게 하면, 해당하는 클래스들을 load 해 준다. 그런데 여기서 load 뿐만 아니라 몇 가지 더 작업을 해주는데 아래와 같다.
- profiles - instantiates each Profile and determines if it should be active. If so, the Profile's own dependencies are also loaded
- controllers - instantiates each Controller after loading
- stores - instantiates each Store, giving it a default store ID if one is not specified
요약하면, profiles, controllers, stores 에 정의된 것들은 load 될 뿐만 아니라 하나의 instance 까지 만들어 주게 된다.
5. controller 와 app 의 메소드 호출 순서
'Sencha Touch 2' 카테고리의 다른 글
HW8 : Sencha Touch 2 Model, Store, Proxy, 이용해서 데이터 받아서 List 에 뿌리기 2 (0) | 2012.07.06 |
---|---|
10일차 : Sencha Touch 2 Model Store Proxy (cont..) (0) | 2012.07.06 |
HW7 : Sencha Touch 2 Model, Store, Proxy, 이용해서 데이터 받아서 List 에 뿌리기 (0) | 2012.07.05 |
9일차 : Sencha Touch 2 Model Store Proxy (1) | 2012.07.05 |
HW5 : Sencha Touch 2 이벤트를 활용해서 버튼이 사라졌다가 버튼이 나오게 하기 (0) | 2012.07.04 |