Managing Dependencies with MVC
센차터치 2 앱에서는 종속적인 관계가 정의될 수 있는 곳이 두 군데 있습니다. 한군데는 application 이고요 다른 곳은 application class 입니다. 이 가이드에서는 앱내에서 어디에 어떻게 종속적인 관계를 정의하는지에 대해 설명 드리겠습니다.
Application Dependencies
MVC 어플리케이션을 생성할 때 Ext.application 에 손쉽게 models, views, controllers, stores, profiles 를 지정할 수 있도록 해 줍니다. 아래 예제가 있습니다.
Ext.application({
name: 'MyApp',
views: ['Login'],
models: ['User'],
controllers: ['Users'],
stores: ['Products'],
profiles: ['Phone', 'Tablet']
});
위 예제에 있는 5개의 configuration option 들은 애플리케이션이 주로 models, views, controllers, stores, profiles 로 구성되는데요 그 각각을 별도의 파일로 만들고 그 만든 파일을 로드할 수 있도록 해 줍니다. 위 예제를 실행하면 센차터치는 아래 경로의 파일들을 로드하게 될 겁니다.
app/view/Login.js
app/model/User.js
app/controller/Users.js
app/store/Products.js
app/profile/Phone.js
app/profile/Tablet.js
위 예제는 아래처럼 Ext.requre를 해서 로드할 수도 있습니다.
Ext.require([
'MyApp.view.Login',
'MyApp.model.User',
'MyApp.controller.Users',
'MyApp.store.Products',
'MyApp.profile.Phone',
'MyApp.profile.Tablet'
]);
애플리케이션에 클래스가 추가되면 추가될 수록 처음의 configurations 방법이 전체 클래스이름을 쓸 필요 없이 파일 이름만 쓰면 되므로 점점 더 효율적이 될 겁니다. 이 방법은 단지 파일을 로딩하는 것 이외에 아래와 같은 일도 추가적으로 하게 됩니다.
* profiles - 각 프로파일들의 instantiate 과 active 여부 판별. active 여부가 판별 되면 해당 프로파일을 로드 함
* controllers - 로딩 후 각 Controller instantiate 함
* stores - 각 Store들 instantiate 하고 아무것도 지정된 것이 없으면 디폴트 store ID 를 세팅함
위 기능들을 이용하기 원하시면 첫번째 configuration options 를 사용하시면 좋습니다.
Profile-specific Dependencies
Device Profile을 사용한다면 특정 디바이스에서만 사용되는 clsss 들이 있을겁니다. 예를 들어 태블릿에서는 폰 보다는 좀 더 많은 기능이 들어갈 겁니다. 그 얘기는 곧 태블릿쪽이 좀 더 많은 클래스를 로드해야 한다는 것이죠. 이 필요한 클래스들은 각각의 프로파일 내에서 정의할 수 있습니다.
Ext.define('MyApp.profile.Tablet', {
extend: 'Ext.app.Profile',
config: {
views: ['SpecialView'],
controllers: ['Main'],
models: ['MyApp.model.SuperUser']
},
isActive: function() {
return Ext.os.is.Tablet;
}
});
이렇게 하면 위 프로파일이 active 되면 config에서 설정한 클래스들이 로드되게 됩니다. 위 태블릿 프로파일이 아니라 폰 프로파일이 active 되면 이 클래스들은 로드되지 않고 폰 프로파일에서 설정한 config에 있는 클래스들이 로드 되겠죠.
이렇게 각 디바이스 별로 프로파일을 만들고 그 프로파일 내에서 필요한 클래스들을 로드 하도록 함으로서 여러분들이 만든 애플리케이션이 특정한 디바이스가 아니라 여러 디바이스에서 사용할 수 있게 됩니다. 앱이 시작할 때 각 프로파일을 체크하고 그 프로파일에 필요한 클래스를 로드하기 때문이죠.
만약 앱의 용량이 아주 클 경우에는 이 방법을 사용해서 처음 앱이 실행될 때 그 앱이 실행된 디바이스에 필요한 클래스들만 다운로드 하도록 만들어서 용량을 줄일 수도 있을겁니다.
Nested Dependencies
규모가 큰 앱에서는 models, views, controllers를 subfolder들로 분리해서 프로젝트를 organize 하는것이 일반적입니다. 특히 views 부분이 더 그런데요. 큰 규모의 앱에서는 수백개의 view 클래스가 있는 것이 흔한일입니다. 그래서 그 클래스들을 더 간단하게 관리할 수 있도록 폴더별로 관리하는 것 입니다.
subfolders로 관리하게 되면 코드상에서 그 경로를 . 로 연결해서 사용하면 됩니다.
Ext.application({
name: 'MyApp',
controllers: ['Users', 'nested.MyController'],
views: ['products.Show', 'products.Edit', 'user.Login']
});
이 5개의 파일들은 아래와 같은 경로에서 로드될 겁니다.
app/controller/Users.js
app/controller/nested/MyController.js
app/view/products/Show.js
app/view/products/Edit.js
app/view/user/Login.js
여기서 각각의 configuration 에서 서로 혼합하거나 match 할 수 있습니다. model, view, controller, profile, store 에 대해 클래스 이름의 마지막 부분을 사용하거나(directory convention을 따르고 있다면) 또느 전체 클래스 이름을 사용할 수 있습니다.
External Dependencies
우리는 앱 외부에 있는 클래스를 로드할 수도 있습니다. 이를 위해 사용하는 일반적인 방법은 여러 어플리케이션 사이에서 authentication(인증) 로직을 공유하는 방법이 있습니다. 아마 여러분의 여러개의 앱이 공동의 유저 데이터베이스에 로그할 필요가 있을 수 있을겁니다. 그럴 경우 그 앱들 사이에서 공통으로 인증 로직을 사용해서 접근하면 됩니다. 이를 위한 쉬운 방법은 폴더를 앱 폴더와 따로 만드는 것입니다. 그리고 여러분의 앱에서 이 폴더에 dependency를 주시면 됩니다.
예를 들어 login controller,유저 모델과 로그인 폼 뷰를 포함한 로그인 코드의 경우를 봅시다. 이 모든것을 어플리케이션 안에서 사용하기를 원합니다.
Ext.Loader.setPath({
'Auth': 'Auth'
});
Ext.application({
views: ['Auth.view.LoginForm', 'Welcome'],
controllers: ['Auth.controller.Sessions', 'Main'],
models: ['Auth.model.User']
});
이럴 경우 아래 파일들을 로드할 겁니다.
Auth/view/LoginForm.js
Auth/controller/Sessions.js
Auth/model/User.js
app/view/Welcome.js
app/controller/Main.js
처음 나오는 세개의 파일이 어플리케이션 밖에 있는 파일을 로드하는 것입니다. 나머지 두개는 앱 내에 있는 파일이구요. 이렇게 함으로서 어플리케이션 파일과 외부의 독립된 파일을 서로 mix하고 match 해서 사용 할 수도 있습니다.
외부 파일을 로드할 수 있도록 하려면 그 파일이 어디에 있는지를 Loader 에게 알려주면 됩니다. 이것은 위 예제에서 Ext.Loader.setPath 에서 한 일입니다. 이 경우 Auth 폴더 안의 Auth namespace로 시작되는 모든 파일을 Loader에게 찾으라고 지시하게 되는 겁니다. 이렇게 함으로서 Auth 코드를 애플리케이션 외부에 따로 떨어뜨려서 관리할 수 있고 그렇게 함으로서 전체 framework이 모든 필요한 것들을 load 하게 됩니다.
Where Each Dependency Belongs
각각의 dependency를 정의하는 장소를 정할 때의 일반적인 룰은 여러분의 클래스들을 완전하게 self-contained 하도록 유지하는 것입니다. 예를 들어 몇개의 다른 뷰를 가지고 있는 한개의 뷰가 있다고 했을 때 그 dependency들은 어플리케이션이 아니라 그 뷰 클래스 안에서 정의해야 합니다.
Ext.define('MyApp.view.Main', {
extend: 'Ext.Container',
requires: [
'MyApp.view.Navigation',
'MyApp.view.MainList'
],
config: {
items: [
{
xtype: 'navigation'
},
{
xtype: 'mainlist'
}
]
}
});
app.js 에서는 아래와 같이 해 줍니다.
Ext.application({
views: ['Main']
});
두가지 이유 때문에 이렇게 dependency들을 정의하는것이 가장 좋은 방법이라고 할 수 있습니다. 첫번째는 MyApp.view.Main을 불러옴으로서 여러분의 app.js 는 간단 명료하게 유지할 수 있고 이러한 dependency들을 이미 다 만족하도록 만들었다는 것을 확인 할 수 있습니다.
//this is bad
Ext.application({
views: ['Main', 'Navigation', 'MainList']
});
간단하게 생각하면 app.js 안에는 단지 top-level 뷰들만 넣으시면 됩니다. 만약 여러분 앱에 Ext.create('MyApp.view.SomeView')를 사용한다면 그 뷰는 top-level일 겁니다. 한 뷰가 다른 뷰의 sub-view라면 (위 예제에서 MyApp.view.Navigation 과 MyApp.view.MainList 같은) 이 뷰는 app.js에 있을 필요가 없습니다.
Changes since 1.x
센차터치 1 (Sencha Touch 1)에서는 Ext.application call 과 같이 콘트롤러 안에서도 사용되어졌었습니다. 이 방법이 편리한 측면이 있지만 Controller 가 너무 뷰,모델, 스토어들을 통제하는 면이 있기도 합니다. 1.x 에서는 아래와 같이 사용할 수 있습니다.
//1.x code, deprecated
Ext.regController('SomeController', {
views: ['Login'],
models: ['User'],
stores: ['Products']
});
이 방법은 Ext.application에서 뷰,모델,스토어를 정의하는 것과 동일합니다. 콘트롤러에서 이 클래스들에 접근하는데에는 편리합니다. 1.x 는 getLoginView()와 getUsermodel() 두개의 함수를 generate 합니다. 그리고 이 콘트롤러에서 정의한 Stores 에 대한 reference를 return 하는 getStore() 함수를 노출시킵니다. 2.x 에서는 이러한 함수들을 사용하지 않습니다. 두가지를 동시에 사용할 수도 잇습니다.
//creating a view - 2.x uses the standardized Ext.create
this.getLoginView().create();
Ext.create('MyApp.view.Login');
//getting a Model - just type out the Model name (it's shorter and faster)
this.getUserModel();
MyApp.model.User;
//Ext.getStore can access any Store whereas the old this.getStore only
//accessed those Stores listed in your Controller
this.getStore('Products');
Ext.getStore('Products');
이 함수들을 없애면 앱을 처음 시작할 때 로딩 시간을 줄일 수 있습니다. 왜냐하면 framework 이 각 콘트롤러에서 정의한 각 모델,뷰에 대한 함수들을 generate 할 필요가 없기 때문입니다. 또한 이러한 함수들을 사용하지 않으면 MVC 모델에 더 부합하는 설계를 할 수가 있습니다.
'WEB_APP > Sencha_Touch' 카테고리의 다른 글
센차터치 2에서 클래스 사용하기. -2- (6) | 2012.04.26 |
---|---|
센차터치 2에서 클래스 사용하기. (0) | 2012.04.24 |
Sencha Touch 2 Tutorial - Layouts - (0) | 2012.04.24 |
Sencha Touch (센차터치) MVC 모델 적용해 보기 (5) | 2012.04.22 |
Sencha Touch 2 Tutorial - Component & Container - (2) | 2012.04.16 |
Sencha Touch 2 Tutorial - History and Deep Link - (1) | 2012.04.13 |
Sencha Touch 2 Tutorial - Device Profiles - 02 (0) | 2012.04.11 |
Sencha Touch 2 Tutorial - Device Profiles - 01 (2) | 2012.04.10 |
Makeing Shopping list app by Sencha Touch - 2 - (0) | 2012.04.07 |
Makeing Shopping list app by Sencha Touch (2) | 2012.04.06 |