この記事はhttp://docs.sencha.com/ext-js/4-0/#!/guide/mvc_pt2の抄訳・意訳です。
Applying the glue
Model,View,Controllerを結合する。
ViewをViewportに追加するのを簡単にする方法がある。
Ext.define('Panda.view.Viewport', { extend: 'Ext.container.Viewport',
ViewportはブラウザいっぱいにContainerを広げる時に使う。
requires: [ 'Panda.view.NewStation', 'Panda.view.SongControls', 'Panda.view.StationsList', 'Panda.view.RecentlyPlayedScroller', 'Panda.view.SongInfo' ],
ViewportからViewへの参照を追加したので、これらのViewをxtypeとして使えるようになった。
layout: 'fit', initComponent: function() { this.items = { xtype: 'panel', dockedItems: [{ dock: 'top', xtype: 'toolbar', height: 80, items: [{ xtype: 'newstation', width: 150 }, { xtype: 'songcontrols', height: 70, flex: 1 }, { xtype: 'component', html: 'Panda<br>Internet Radio' }] }], layout: { type: 'hbox', align: 'stretch' }, items: [{ width: 250, xtype: 'panel', layout: { type: 'vbox', align: 'stretch' }, items: [{ xtype: 'stationslist', flex: 1 }, { html: 'Ad', height: 250, xtype: 'panel' }] }, { xtype: 'container', flex: 1, layout: { type: 'vbox', align: 'stretch' }, items: [{ xtype: 'recentlyplayedscroller', height: 250 }, { xtype: 'songinfo', flex: 1 }] }] }; this.callParent(); } });
ViewportはContainerのサブクラスであり、docked itemsを持てないので、panelを子Componentとしてpanelにdocked itemsを設定している。
レイアウトのConfig(height,widthなど)を書かずにレイアウトできているというのは非常に重要。
これによって簡単にレイアウト調整が可能になる。メンテナンス性が向上する。
Application logic
Extjs3ではViewにロジックを書いてしまいがちだったが、Extjs4ではControllerがあり、ロジックとレイアウトを分離しやすくなった。
コレによって以下のメリットが得られる。
・ロジックを実行中にViewをDestroyできる。
・Extjs3ではロジックを持ったViewがネストしてアプリが複雑になりやすかった。ロジックとViewを分割することでメンテナンス性が向上する。
Creating our Controllers
StationとSongのControllerを定義する。
app/controller/Station.js
Ext.define('Panda.controller.Station', { extend: 'Ext.app.Controller', init: function() { ... }, ... });
app/controller/Song.js
Ext.define('Panda.controller.Song', { extend: 'Ext.app.Controller', init: function() { ... }, ... });
applicationメソッド内でControllerがロードされた時に、Controllerのinitメソッドも実行される。
initメソッド内でViewのlistenerにイベントハンドラを紐付ける。
他のコントローラを使いたければgetControllerでコントローラをロードする。
someAction: function() { var controller = this.getController('AnotherController'); // Remember to call the init method manually controller.init(); }
getControllerでControllerをロードした場合は手動でinitしないといけないので注意。
ControllerをApplicationに追加してロードしておくこと。
app/Application.js
Ext.application({ ... controllers: ['Station', 'Song'] });