業務アプリデモ開発をベースにhifiveを学ぼう(3)「ツリービューの実装」
前回に引き続いて今回はツリービューを実装します。動作は次のようになります。
要件としては
- ツリービューの初期表示
- ツリービューの折りたたみ、伸張
となります。
JS Treeビューの導入
ツリービューの表示自体はjsTreeというライブラリを使います。
このライブラリをlib/jstree以下に配置し、index.htmlにて読み込みます。
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
<!– jstree –> | |
<link rel="stylesheet" href="lib/jstree/themes/default/style.css" /> | |
<script type="text/javascript" src="lib/jstree/jstree.js"></script> |
js/AppPurchaseManagerController.jsの修正
次に 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
var controller = { | |
: | |
_treeViewController: sample.TreeViewController, |
さらに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
var controller = { | |
: | |
_appLogic: sample.AppPurchaseManagerLogic, |
そして、コントローラーが使える状態になったタイミングのイベント、__readyにてツリービューコントローラーを呼び出します。
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
__ready: function() { | |
// ツリービュー(エクスプローラ)にデータを設定 | |
this._treeViewController.setTreeData(this._appLogic.getShortcutTree()); | |
}, |
これでコントローラの修正は完了です。
AppPurchaseManagerLogicの処理
次にAppPurchaseManagerLogicについて記述していきます。ファイルは js/AppPurchaseManagerLogic.js になります。処理内容は次のようになります。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
(function() { | |
var controller = { | |
__name: 'sample.AppPurchaseManagerLogic', | |
getShortcutTree: function() { | |
return sample.util.ajax(sample.consts.url.FILE_TREE); | |
} | |
}; | |
h5.core.expose(controller); | |
})(); |
sample.consts.url.FILE_TREE は sample.util 内で定義される変数です。
AppPurchaseManagerLogicを読み込むように index.html を修正しておきます。
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
<script src="js/AppPurchaseManagerLogic.js" /></script> |
util.jsの修正
ここでは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
h5.u.obj.expose('sample.util', { | |
: | |
ajax: function(url, data) { | |
// ダミーデータを返す | |
var ret = null; | |
url = url.url || url; | |
switch (url) { | |
case sample.consts.url.FILE_TREE: | |
ret = treeDatas || createTreeDatas(); | |
ret = ret.slice(0); | |
break; | |
} | |
var dfd = h5.async.deferred(); | |
setTimeout(function() { | |
dfd.resolve(ret); | |
}, 0); | |
return dfd.promise(); | |
} |
ダミーデータは一覧などでも使うのでswitch文を使って取り分けられるようにしています。今回は createTreeDatas()
にてデータを生成します。
続けて createTreeDatas()
を実装します。 applicants
と statuses
は他の処理でも使うので関数の外に出しています。
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
var applicants = ['satoshi', 'takeshi', 'kasumi', 'haruka']; | |
var statuses = ['new', 'investigation', 'approved', 'closed', 'rejected']; | |
function createTreeDatas() { | |
treeDatas = [{ | |
id: 'all', | |
parent: '#', | |
icon: 'jstree-file', | |
text: '全て' | |
}, { | |
id: 'applicant', | |
parent: '#', | |
text: '申請者別', | |
state: { | |
opened: true | |
} | |
}, { | |
id: 'status', | |
parent: '#', | |
text: 'ステータス別', | |
state: { | |
opened: true | |
} | |
}, { | |
id: '10000*100', | |
parent: '#', | |
text: '10000×100', | |
icon: 'jstree-file' | |
}, { | |
id: '10000*10000', | |
parent: '#', | |
text: '10000×10000', | |
icon: 'jstree-file' | |
}]; | |
// 申請者別 | |
for (var i = 0, l = applicants.length; i < l; i++) { | |
var applicant = applicants[i]; | |
treeDatas.push({ | |
id: 'applicant.' + applicant, | |
parent: 'applicant', | |
icon: 'jstree-file', | |
text: applicant | |
}); | |
} | |
// ステータス別 | |
for (var i = 0, l = statuses.length; i < l; i++) { | |
var status = statuses[i]; | |
var text = sample.util.statusTextMap[status]; | |
treeDatas.push({ | |
id: 'status.' + status, | |
parent: 'status', | |
icon: 'jstree-file', | |
text: text | |
}); | |
} | |
return treeDatas; | |
} |
treeDatasというツリービューの元データを作成して返しています。この中で sample.util.statusTextMap という変数を使っていますので、これは sample.utilsの中で定義しておきます。
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
h5.u.obj.expose('sample.util', { | |
statusTextMap: { | |
'new': '新規', | |
investigation: '検討中', | |
approved: '承認済', | |
closed: '完了', | |
rejected: '棄却' | |
}, | |
: |
最後に定数用のオブジェクトを定義します。
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
h5.u.obj.expose('sample.consts', { | |
url: { | |
FILE_TREE: 'filetree' | |
} | |
}); |
これでutil.jsの修正は完了です。
js/TreeViewController.jsの追加
最後に js/TreeViewController.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
var controller = { | |
__name: 'sample.TreeViewController', | |
_$tree: null, // ツリービューのDOM | |
_currentSelected: null, // 選択しているデータについて | |
__init: function() { | |
// 初期設定 | |
}, | |
setTreeData: function(dataOrPromise, opt) { | |
// ツリービューにデータをセット | |
}, | |
h5.core.expose(controller); | |
})(jQuery); |
まず初期設定を行います。
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
__init: function() { | |
sample.util.createDefaultControllerView(this); | |
this._$tree = this.$find('.jstree'); | |
}, |
ここで sample.util.createDefaultControllerView(this);
とすることで表示処理の下準備(バインド)を行っています。
そして setTreeData を実装します。これはデータを受け取って描画を行う処理になります。
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
setTreeData: function(dataOrPromise, opt) { | |
if (h5.async.isPromise(dataOrPromise)) { | |
var indicator = this.indicator().show(); | |
dataOrPromise.done(this.own(function(treeData) { | |
this._setTreeData(treeData, opt); | |
indicator.hide(); | |
})); | |
} else { | |
this._setTreeData(dataOrPromise, opt); | |
} | |
}, |
ここで注意するのはAjaxのような非同期処理とそうでない場合を想定しておくということです。その判定として、hifiveでは h5.async.isPromise というメソッドを提供しています。これを使うことで Promiseであればdoneメソッドを受けてから表示処理を行うといった判定ができます。また、Promiseの場合は var indicator = this.indicator().show();
を使ってインジケータ表示を行っています。これは標準で用意しているメソッドになります。
_setTreeData
については以下のようになります。JSTreeを呼び出してデータを設定しているだけです。this.$treeには元々jQueryが入っています。
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
_setTreeData: function(treeData, opt) { | |
// TODO 各オプションは設定可能 | |
opt = opt || {}; | |
this._$tree.jstree({ | |
core: { | |
animation: opt.animation || 0, | |
multiple: opt.multiple || false, | |
data: treeData | |
}, | |
themes: opt.themes || { | |
stripes: true | |
} | |
}); | |
} |
なお、このファイルもindex.htmlから読み込まれるように指定します。
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
<script src="js/TreeViewController.js"></script> |
これで準備完了です。実行すると、ツリービューが表示されるかと思います。
今回はデモなのでデータを手動で用意していますが、実際にはAjaxを使ってサーバから取得することになるかと思います。しかし、その場合もutil.jsさえ切り替えれば良いだけです。
このようにAjaxによるデータ取得部分をコントローラによる処理と切り離しておくことでメンテナンス性をあげることができます。さらに同期、非同期処理の両方に対応しておくことでコードも見やすくなるはずです。
今回のコードはGitHubで見られるようになっています。また、動作しているデモはこちらになります。
次回はデータの一覧表示部分について見ていきます。
コメントは受け付けていません。