Ractive.jsとは
データバインドに特化したjsライブラリです。
状態監視にVirtualDomの概念を用いているため、挙動が軽く高速です。
実装をテンプレートと、それを監視するRactiveモデルに分離することで、デザインとロジックの分離を実現できます。
モデル設定の記述が直感的かつシンプルで、初見の開発者でも何となく実装を理解できることが強みです。
またテンプレートに必要最低限のロジックを備えているため、複雑なオブジェクトの展開も難なく行うことが出来ます。
Vue.jsほど対応ブラウザに偏りがなく、Angular.jsほど巨大ではない、
データバインドを手軽に取り入れたい際に非常に便利なライブラリです。
Knockout.jsとは立ち位置が似ているので、記法が好みな方を選べばいいのではないかと個人的には思っています。
対応ブラウザ
GithubのReadmeでは「__IE8__以上の全てのモダンブラウザでテストされている」と表現されています。
リポジトリのpackage.jsonを見ると以下の記述があり、こちらに列挙されているブラウザについては挙動が保障されているようです。
"testling": {
"html": "test/testling.html",
"browsers": [
"ie/8..latest",
"chrome/10.0",
"chrome/15.0",
"chrome/23..canary",
"firefox/3.6",
"firefox/7.0",
"firefox/12.0",
"firefox/18.0..nightly",
"opera/10..next",
"safari/4..latest",
"iphone/6.0",
"ipad/6.0",
"android-browser/4.2"
]
}
基本的な使い方
テンプレートとRactiveモデル
テンプレートとその展開先を定義します。
type="text/ractive" に設定したscriptタグで囲った部分がテンプレートとなり、Ractiveモデルの監視対象となります。
<div id="container"></div>
<script id="template" type="text/ractive">
<p>{{key1}}</p><p>{{key2}}</p>
</script>
__el__にテンプレートを展開する先のidを、__template__にテンプレートのidを記述します。
__data__は必ずオブジェクト型にして、内部にデータバインドを行いたい値を列挙します。
var model = new Ractive({
el: '#container',
template: '#template',
data: {
key1: 'Hello',
key2: 'World!!',
}
});
以上を記述して実行すると以下のHTMLが表示されます。
<div id="container">
<p>Hello</p><p>World!!</p>
</div>
関連記事: Ractive.jsのテンプレートの使い方まとめ
http://qiita.com/morisuke/items/8f2005355a96fa25567a
データバインド
2.1_Templateのようにテンプレートにinputとpタグを書き、それぞれのvalueと表示領域を{{name}}で関連付けます。
2.2_Modelを実行し、画面上のinputに文字列を入力すると、pタグの中に入力した文字列が表示され、
またRactiveモデル内部のdata.nameも入力した文字列に更新されています。
2.3_Setの例に示すようにsetメソッドを発行することでデータを置き換え、画面上の表示を更新することもできます。
このようにデータと表示領域が連動する仕組みのことをデータバインドと呼びます。
<div id="container">
<script id="template" type="text/ractive">
<input value='{{name}}'>
<p>{{name}}</p>
</script>
</div>
var model = new Ractive({
el: '#container',
template: '#template',
data: {
name: null
}
});
model.set('name', 'example');
バインド中のデータの監視
Ractiveモデルに対してobserveメソッドを発行することでデータの更新を検知することが出来ます。
画面上からの入力、setメソッドによる書き換えの双方を検出し、第二引数に渡されたコールバック関数を呼び出します。
3.1_Observeの例ではnameの変更を監視し、valueにはその時入力された値が渡されます。
model.observe('name', function(value){
console.log(value);
});
関連記事: Ractive.jsでイベントを拾う方法まとめ
http://qiita.com/morisuke/items/495d0198085c330e4b88
実践的なコード
ここでは、セレクトボックスの内容によって異なるAPIをAjaxで叩き、結果を取得表示する例を示します。
RactiveにはAjax関連のモジュールが無いため、jQueryも使用しています。
またスクリプトは必ず</body>
の直前に記述するか、$(function(){})
で囲ってください。
Ractiveモデルの起動時にテンプレートの展開先を見つけることが出来ずスクリプトが落ちます。
<div id="selectContainer">
<script id="selectTemplate" type="text/ractive">
<select value="{{selected}}">
{{#options}}
<option value="{{apicode}}">{{label}}</option>
{{/options}}
</select>
</script>
</div>
<div id="displayContainer">
<script id="displayTemplate" type="text/ractive">
{{result}}
</script>
</div>
// APIデータ取得モデルの設定
var displayModelSetting = {
el: '#displayContainer',
template: '#displayTemplate',
data: {
apicode: null,
result: null
},
// newされた時に動作する
onrender: function(){
// data.apicodeを監視
this.observe('apicode', function(apicode){
if (! apicode){
return false;
}
$.ajax({
url: 'http://******',
type: 'post',
dataType: 'json',
data: {code: apicode}
})
.done(function(res){
// data.resultに返ってきたjsonを文字列に変換して収める
this.set('result', JSON.stringify(res));
})
});
}
};
// セレクトボックスモデルの起動
var selectModel = new Ractive({
el: '#selectContainer',
template: '#selectTemplate',
data: {
// display Ractiveモデルの起動
display: new Ractive(displayModelSetting),
// この配列の中身が<option>に展開される
options: [
{apicode: 1, label: '1番のAPIを選択'},
{apicode: 2, label: '2番のAPIを選択'},
{apicode: 3, label: '3番のAPIを選択'},
],
selected: null
},
onrender: function(){
this.observe('selected', function(apicode){
if (! apicode) {
return false;
}
// display Ractiveモデルを取得してapicodeをセット
this.get('display').set('apicode', apicode);
})
},
});
テンプレートの{#*****}
から{/*****}
でセレクトモデルのoptionsを展開し、<option>
を動的に生成しています。
そうして生成されたセレクトボックスを選択する度にselectedの値が変更され、セレクトモデルのobserve
が検知します。
セレクトモデルはディスプレイモデルにapicodeを投げ渡し、ディスプレイモデルがその値を元にAjaxでデータを取得します。
データを更に複雑な構造に展開することが求められる場合にも、jQueryで一々Domを組む必要はありません。
最初に展開用のテンプレートを用意しておいてそこにデータを流し込むだけです。
このようにHTML要素の「見え方」をテンプレートで定義し、「挙動」と「関連性」をRactiveモデルでラッピングしていくことで、Viewとロジックが明確に分離された見通しの良いコードを組んでいくことが出来ます。
最後に
こちらの記事は今後も継続的に更新を続けていきます。
また日本のRactive.jsユーザの皆様にお願いです。
今はまだRactive.jsの日本語ドキュメントが非常に少ない状況です。
Qiitaでもブログでも良いので、些細な情報でも構いません、情報発信をして頂けますと幸いです。