Riot.js はカスタムタグを追加していくことで、ひとつのアプリケーションを構築していきます。
たいていのアプリケーションでは外部の RESTful API を呼び出して、そのデータを元に UI を組み立てていきたいと考えるでしょう。
Riot.js のカスタムタグを使って、Facebook のいいね数を取得して表示するというシンプルなカスタムタグを作ってみます。さらに今回は、HTML の新たな標準仕様 Fetch を使って標準的なやりかたで取得します。
TL;DR
<sns-count-facebook>
というカスタムタグを定義して、以下のように呼び出すことを前提にします。
<sns-count-facebook url="https://www.google.com"></sns-count-facebook>
カスタムタグの定義はこんな感じになります。
<sns-count-facebook>
<span>{ count }</span>
<script>
this.count = '( Loading... )'
var self = this
fetch( 'https://api.facebook.com/restserver.php?method=links.getStats&format=json&urls=' + opts.url )
.then( function ( data ) {
return data.json()
} )
.then( function ( json ) {
self.count = json[ 0 ].total_count
self.update()
} )
</script>
</sns-count-facebook>
ES2015 に対応している場合は 後述 のようにシンプルに記述できます。
では詳しく見ていきます。
まずは静的なカスタムタグを定義
分かりやすくするために Facebook の RESTful API を呼び出さない状態から作ってみます。
<sns-count-facebook>
<span>{ count }</span>
<script>
this.count = '( Loading... )'
</script>
</sns-count-facebook>
表示はこうなります。
( Loading... )
もちろんこのままでは使い物になりません。
Fetch を使って Facebook の RESTful API を呼び出してみます。
RESTful API の呼び出し
Facebook の RESTful API を呼び出す Fetch はこのようなコードになります。
fetch( 'https://api.facebook.com/restserver.php?method=links.getStats&format=json&urls=' + url )
.then( function ( data ) {
return data.json()
} )
.then( function ( json ) {
console.log( json )
} )
Ajax は面倒なので jQuery の $.ajax()
を使いたくなりますが、今や標準でも十分便利な API ができています。
そもそも Ajax は XMLHttpRequest( XHR )を利用した 手法 の話ですが、Fetch は 低レベルの API です。しかも、何もしなくても Promise を返してくれます。
Riot.js には Fetch や Ajax 関連の API はありませんが、標準でできることは標準でやるのが Riot.js の方針です。
ただし Fetch はまだモバイルブラウザなどが対応していないので、この polyfill を利用すると便利です。
完成
カスタムタグに Fetch を追記すれば完成です。
<sns-count-facebook>
<span>{ count }</span>
<script>
this.count = '( Loading... )'
var self = this
fetch( 'https://api.facebook.com/restserver.php?method=links.getStats&format=json&urls=' + opts.url )
.then( function ( data ) {
return data.json()
} )
.then( function ( json ) {
self.count = json[ 0 ].total_count
self.update()
} )
</script>
</sns-count-facebook>
count
というテンプレート変数にはデフォルトで ( Loading... )
を入れておいて、Facebook からのレスポンスによって書き換えます。
ポイントは、this
を self
にアサインしていることです。
Riot.js はユーザーのインタラクション( onclick
など )に応じたデータストアの更新は自動的に UI に反映してくれますが、Fetch などそれ以外の場合は this.update()
を明示的に呼び出す必要があります。1
しかし、Fetch の中では this
が Riot.js のタグインスタンスを指さないため、事前に self
のようなその他の変数にアサインしておく必要があります。
モダンな環境では
ES2015 が利用できる環境か ES5 へのトランスパイルする場合には、アロー関数によってシンプルに書くことができます。
<sns-count-facebook>
<span>{ count }</span>
<script>
this.count = '( Loading... )'
fetch( 'https://api.facebook.com/restserver.php?method=links.getStats&format=json&urls=' + opts.url )
.then( data => data.json() )
.then( json => {
this.count = json[ 0 ].total_count
this.update()
} )
</script>
</sns-count-facebook>
カスタムタグの応用
先ほど作った <sns-count-facebook>
タグは、単純に Facebook でのいいね数を数字で表示するだけです。
実際には他のカスタムタグから呼び出されることによって、Riot.js の効果を発揮します。
例えば、指定した複数のサイトのいいね数を出す <sns-count>
というタグを定義してみます。
<sns-count>
<p each="{ opts.items }">
{ title } の Facebook いいね数は <sns-count-facebook url="{ url }"></sns-count-facebook> です。
</p>
</sns-count>
この <sns-count>
タグを以下のようにマウントすると...
riot.mount( 'sns-count', {
items : [
{ title : 'Google', url : 'https://www.google.com' },
{ title : 'Facebook', url : 'https://www.facebook.com' },
{ title : 'Twitter', url : 'https://www.twitter.com' }
]
} )
このように表示されます。
Google の Facebook いいね数は 3704625 です。
Facebook の Facebook いいね数は 75911262 です。
Twitter の Facebook いいね数は 526350 です。
Facebook のいいね数を取得/表示するという一連のロジックを呼び出す側から隠蔽できました。
ライブデモ
ご自分で試されたいという方は Plunker に ライブデモ を置いたので、いろいろ弄ってみてください。
-
公式ドキュメントより > http://riotjs.com/ja/api/#tag-update ↩