表示の更新部分の理解
先ほど、サーバー側でデータを追加すると、ブラウザの表示も更新されたと思います。この部分がMeteor.jsでリアクティブプログラミングをする楽しいところだと思います。
それでは、クライアント側の関連するコードを見ていきましょう。
Template.textChat.helpers({ messages: Messages.find({}, {sort:{timestamp: 1}}) });
先ほど、サーバー側でデータを挿入したら、それがクライアント側にも同期されました。そうすると、ヘルパで定義しているmessagesが更新されます。そして、テンプレート側で参照している部分が反応し、表示が更新されます。
<template name="textChat"> <div id="chat-messages"> {{#each messages}} {{> message user=user text=text timestamp=timestamp}} {{/each}} </div> </template>
イベントのハンドリングとリモートプロシージャコールの理解
今回は、「Send」ボタン、もしくは「Enter」を押下したら、テキストフィールドに入力されている値をデータベースに登録します。その部分を見ていきましょう。
<template name="inputBox"> <div class="row"> <div class="input-field input-box col s12"> <input type="text" id="input-box-text" class="col s8" /> <button id="send" class="waves-effect waves-light btn">Send</button> <label for="input-box-text">Messages: </label> </div> </div> </template>
inputBoxというテンプレート名で定義しており、そのハンドリングは、下記のコードで行っています。'keypress input'、'click button'でイベント名と対応する要素を指定しています。今回inputBoxのテンプレートのhtmlには、input、button要素はそれぞれ1つなので、何か他のinput, button要素と競合することはありません。
Template.inputBox.events({ 'keypress input': function(e) { return newMessage(e); }, 'click button': function(e) { return newMessage(e, true); } }); function newMessage(e, isButtonClick) { var inputVal = $('#input-box-text').val(); if(!!inputVal) { var charCode = (typeof e.which == "number") ? e.which : e.keyCode; if (charCode == 13 || isButtonClick) { e.stopPropagation(); Meteor.call('newMessage', {user: $('#caller-id').val(), text: $('#input-box-text').val()}); $('#input-box-text').val(""); return false; } } }
newMessage内の処理で、Meteor.call('newMessage', ...)というものがあります。これは、リモートプロシージャコールです。クライアント側からサーバーサイド側で定義されたメソッドをコールします。サーバーサイドに、newMessageというメソッドが定義されているので、それがコールされます。
Meteor.methods({ newMessage: function (message) { message.timestamp = Date.now(); Messages.insert(message); } })
今回はシンプルにするために、サーバー側のデータベースを更新してからクライアント部分を更新するという流れになっていますが、Meteor.jsの公式ページには以下のような図があり、この中では、平行してクライアント側も先に更新した方がよいとあります。これは、サーバー側にアクセスするためのネットワークの遅延があるためです。
詳細は、上記のリンクの記事を参考にしてみてください。
Meteor.jsを理解するにあたって、これらの流れを頭に入れておくと分かりやすくなると思います。これらが主にテキストチャットの部分のコードになります。では、次にこのテキストチャットもアプリ化していきましょう。