背景
現在のプロジェクトではjQueryを使ってDOM操作しているけれども、DOM操作だけはRiot.jsに置き換えたい。
そのようなときに、Riot.jsのコンポーネントと既存の処理をどのように連携させたらよいのか...
ということで、Riot.jsの外からRiot.jsのコンポーネントに処理を移譲する方法を調べていました。
解決策の概要
Riot.jsを使っていない既存の処理から、Riot.jsのコンポーネントにデータを流し込んで表示させる場合、オブザーバブルという機構をつかって実現できます。
コンポーネント間の通信でも、この方法を利用します。
【Riot.js】タグ間で動作を連動させるというエントリを参考にさせていただきました。
実装サンプル
サンプルとして、jQueryでajax通信した後、JSONで受け取った結果を表示するコンポーネントを作るとします。
ここでは、result-listというコンポーネントを生成しています。
オブザーバブルオブジェクトを生成して、コンポーネントのマウント時に引き渡します。
var observer = riot.observable();
riot.mount('result-list', {observer:observer});
result-listは以下のように定義されています。
マウント時の第二引数の値には、optsという変数でアクセスできるようになっています。
マウント時に引き渡されたオブザーバブルオブジェクトに対して、リスナーを登録します。
<script type="riot/tag">
<result-list>
<ul>
<li>{ title }</li>
<li>{ message }</li>
</ul>
var self = this
// mount時にobserverを受け取る
self.observer = opts.observer
// 外部からobserver.trigger('result-list:refresh', result)を呼びだされたら発動
self.observer.on('result-list:refresh', function(result) {
self.title = result['title']
self.message = result['message']
self.update()
})
</result-list>
</script>
外からデータを反映したいタイミングでoberver.triggerを呼び出します。
今回のサンプルの場合は、ajax通信後のcallbackで呼び出してみます。
$.getJSON(url, data, function(json){
observer.trigger('result-list:refresh', json);
});
この方法で、Riot.jsのコンポーネント外からデータを流し込むことができました。
ReactJS等の導入になかなか踏みきれないけど、jQueryでのDOM操作はいい加減やめたい。
そのような方にとって参考になればと思います。