業務アプリデモ開発をベースにhifiveを学ぼう(5)「親子連携」
今回は引き続き業務アプリのデモを通じてhifiveの機能を紹介します。今回は親子連携についてです。
親子連携はいわゆる Master – Detailと呼ばれるもので、親で選んだ内容を子に伝えることで描画を更新したり、処理を行うというものになります。
今回のデモでは2つの親子連携が行われています。
ツリービューでの選択
ツリービューで項目を選択すると、右側のグリッドが更新されます。この処理は js/AppPurchaseManagerController.js に記載されています。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'.shortcut selected': function(ctx) { | |
: | |
this._gridViewerController.setData(this._appLogic.searchPurchaseDatas(query)); | |
} |
queryというのは絞り込み条件になります。それを使って js/AppPurchaseManagerLogic.js の searchPurchaseDatas を呼び出します。実際にはutil.ajaxを使っています。結果はグリッドで描画するデータの配列になります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
searchPurchaseDatas: function(query) { | |
return sample.util.ajax(sample.consts.url.SEARCH_WORKFLOW, query); | |
}, |
GridViewerController.js の setData ではデータを受け取った後、描画処理を行います。ここで注意したいのは、データがPromiseオブジェクトの場合があるということです。その場合、Promiseであるかどうかを判定し( if (h5.async.isPromise(data)) {
)その結果を使って再度自分自身をコールしています。これによって非同期処理でも同期のように扱えるようになります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
setData: function(data, dummyColNums) { | |
if (h5.async.isPromise(data)) { | |
var indicator = this.indicator(); | |
indicator.show(); | |
data.done(this.own(function(d) { | |
this.setData(d, dummyColNums); | |
indicator.hide(); | |
})); | |
return; | |
} | |
this._gridWrapperController.setData(data, dummyColNums); | |
this.$find('.dataLength').text(data.length); | |
}, |
実際には js/grid/GridWrapperController.js の setData に処理を委譲しています。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
setData: function(data, dummyColNums) { | |
this._gridController.setData(data, dummyColNums); | |
}, |
さらに処理を js/grid/DatagridController.js に処理を渡しています。ここで実際の表示処理を行っています。画面を部品ごとに分割したり、ラッパーを挟むことで機能を分割できるようになり、メンテナンス性が維持されます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
setData: function(data, dummyColNums) { | |
: | |
var dataSource = datagrid.createDataSource({ | |
idProperty: 'id', | |
type: 'local', | |
param: data | |
}); | |
// paramを再生成する | |
this._createDefaultParam(dummyColNums); | |
// FIXME (0,0)にグリッドをスクロール | |
this._gridController._viewController._vPos = 0; | |
this._gridController._viewController._hPos = 0; | |
this._gridController.activate(dataSource, this._param); | |
this._gridController.search(); | |
this._triggerLengthChange(); | |
}, |
グリッドで選択
グリッドで行を選択した後のイベントは次のように処理されます。まず行を選択した時点で gridChangeDataSelect
イベントが呼ばれます。処理を行うのは js/grid/DatagridController.js です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'{rootElement} gridChangeDataSelect': function() { | |
var ids = this._gridController.getSelectedDataIdAll() | |
this.trigger('showDetail', ids); | |
}, |
ここでは選択されているIDを集めて、showDetailイベントを発火しています。このイベントは js/AppPurchaseManagerController.js によって監視されています。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'.gridViewer showDetail': function(ctx) { | |
var id = ctx.evArg; | |
if (!id) { | |
return; | |
} | |
var isMass = ($.isArray(id) ? id[0] : id).indexOf('_') === '0'; | |
var data = this._appLogic.getPurchaseById(id); | |
this._detailController.setData(data, isMass); | |
}, |
そして js/DetailController.js
のsetDataが呼ばれます。ここではデータを作成し、 view.updateを使って描画処理を行います。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
setData: function(data) { | |
: | |
var dataAry = $.isArray(data) ? data : [data]; | |
var details = []; | |
for (var i = 0, l = dataAry.length; i < l; i++) { | |
var d = dataAry[i]; | |
details.push({ | |
id: d.id, | |
: | |
applicationDate: d.applicationDate | |
}); | |
} | |
this.view.update('{rootElement}', 'purchaseDetail', { | |
details: details | |
}); | |
this.refresh(); | |
}, |
その他の処理
その他、画面上でボタンを押した際の処理などがありますが、いずれも実際の処理は行わずにイベントを発火しています。例えば以下は承認済みにする処理です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'.confirm click': function(ctx, $el) { | |
var ids = '' + $el.data('confirm-targets'); | |
ids = ids.split(','); | |
if (!ids.length) { | |
return; | |
} | |
if (!confirm(ids.length + '件のデータを"承認済"にします。よろしいですか?')) { | |
return; | |
} | |
this.trigger('confirmPurchase', { | |
ids: ids | |
}); | |
}, |
confirmPurchaseというイベントは js/AppPurchaseManagerController.js にて購読しています。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'{rootElement} confirmPurchase': function(ctx) { | |
var ids = ctx.evArg.ids; | |
var promise = this._appLogic.confirmByIds(ids); | |
this.indicator({ | |
promises: promise | |
}).show(); | |
promise.done(this.own(function(datas) { | |
this._detailController.confirmExecuted(datas); | |
this._gridViewerController.refresh(); | |
alert(datas.length + '件の申請を承認しました'); | |
})); | |
}, |
このように hifive では購読とイベントを使ってデータの伝搬と描画を行っています。その結果としてHTMLとデータ操作を分離し、メンテナンスやテストしやすいシステム構築が可能になります。
今回のコードはGitHubにアップロード されています。また、デモはこちらにて試せます。
hifiveではこのような構築法が容易になるように設計されています。ぜひお試しください。
コメントは受け付けていません。