体感!JavaScriptで超速アプリケーション開発 -Meteor完全解説

第6回Meteorテンプレートをもっと活用する

今回は、テンプレートに関する残りの話題として、テンプレート内にイベントハンドラを登録する仕組みや、テンプレートに関するAPIを紹介します。

テンプレート内のイベントを捕捉する

Meteorのテンプレートシステムを使用すると、テンプレート内で発生したイベントを捕捉するようなコードも簡単に記述することができます。

たとえば、以下のようなHTMLコードがあるとします。<body>に埋め込まれるテンプレートの名称はmainContentで、その中にボタンが2つあります。ボタンのIDは「goodMorning」「hello」です。

<head>
  <title>サンプル6-1</title>
</head>
<body>
  
</body>
<template name="mainContent">
  <button id="goodMorning">Good Morning</button>
  <button id="hello">Hello</button>
</template>

これらのボタンがクリックされた時に処理を行うには、テンプレートmainContentが持つeventsメソッドを使用し、イベントを定義します。

Template.mainContent.events({
    // Helloボタンのクリックイベント
    'click #hello': function(event, template) {
        alert('Hello');
    },
    // Good Morningボタンのクリックイベント
    'click #goodMorning': function(event, template) {
        alert('Good Morning');
    },
    // テンプレート内のボタンがクリックされたら呼び出される
    'click button': function(event, template) {
        alert('ボタンがクリックされました');
    }
});

eventsメソッドは、決められた形式のJavaScriptオブジェクト(イベントマップ)を引数にとります。イベントマップは文字列をキー、関数オブジェクトが値となります。

イベントマップのキーは、以下の形式に従った文字列です。

イベント名[,イベント名...] セレクタ

上のコードでは、"click #hello"は「#helloというIDの要素のクリックイベント⁠⁠、"click button"は「button要素のクリックイベント」という意味になります。また、イベント名はカンマで区切って複数指定できます。

イベントハンドラとなる関数オブジェクトは、2つの引数をとります。1つ目はイベントオブジェクト、2つ目はテンプレートのインスタンスです。

上記のコードを実行すると、ボタンが2つ表示され、それらをクリックするとアラートが2回表示されます。これは、IDを対象としたイベントハンドラと、button要素を対象としたイベントハンドラのどちらも実行されているからです。

図1 サンプル6-1の実行結果(その1)
図1 サンプル6-1の実行結果(その1)
図2 サンプル6-1の実行結果(その2)
図2 サンプル6-1の実行結果(その2)

サンプルは以下からダウンロードできます。

テンプレートのAPI

<template>要素はMeteorによってコンパイルされ、グローバル変数Templateに関数オブジェクトとして登録されます第4回を参照⁠⁠。その関数オブジェクトは、ただ実行することができる(実行するとテンプレートの評価結果が得られます)だけではなく、以下のようなAPIを備えています。

  • rendered…テンプレートの実行結果がDOMに挿入される時呼び出されるイベントハンドラです。
  • created…テンプレートが作成された時に呼び出されるイベントハンドラです。
  • destroyed…テンプレートが破棄された時に呼び出されるイベントです。

これらのメソッドは、テンプレートに設定するイベントハンドラです。以下のように指定します。

Template.mainContent.created = function() {
    console.log('created');
};
Template.mainContent.rendered = function() {
    console.log('rendered');
};
Template.mainContent.destroyed = function() {
    console.log('destroyed');
};

また、以下のメソッドはすでに説明済み、もしくは次回以降に説明を行います。

  • events(eventmap)…イベントマップを登録します(上記で説明済み)
  • helpers(helpers)…ヘルパー関数を登録します(前回説明済み)
  • preserve(selectors)…テンプレートの再レンダリングが行われた際、以前のDOMノードの状態を引き継ぎたい要素を、セレクタで指定します。テンプレートの再レンダリングについては、ライブHTMLという概念の理解が必要なので、今回は説明しません。

テンプレートのインスタンスが持つメソッド

上で説明したメソッドは、Meteorによって生成されたテンプレート関数が静的に持つAPIでした。ここでは、テンプレート「インスタンス」が持つAPIを説明します。

テンプレートのインスタンスは、以下の状況で利用できます。

まず、テンプレートのrendered、created、destroyedなどのイベントハンドラ内におけるthisオブジェクトは、テンプレートインスタンスを参照しています。

Template.mainContent.created = function() {
    // thisが指すのはテンプレートのインスタンス
    var template =  this;
};

また、テンプレート内のUI要素から発生したイベントの、イベントハンドラの第二引数に渡されます。

// イベントマップの登録
Template.mainContent.events({
    // イベントハンドラの第二引数がtemplate
    'click #greeting': function(event, template) {
    ...
    }
});

テンプレートのインスタンスは、以下のようなAPIを備えています。

  • findAll(selector)…セレクタを文字列で受け取り、テンプレート内でマッチする要素を全て返します。
  • find(selector)…セレクタを文字列で受け取り、テンプレート内でマッチする要素をひとつ返します。存在しない場合はnullを返します。
  • firstNode…テンプレート内の最初の要素を返します。
  • lastNode…テンプレート内の最後の要素を返します。
  • data…テンプレートが呼び出された際に渡されたデータを返します。

テンプレートインスタンスが持つAPI(ここではfindを使用する例を挙げます。

テキストフィールドとボタンが1つずつ記述された、以下のようなHTMLがあるとします。

<head>
  <title>サンプル6-2</title>
</head>
<body>
  
</body>
<template name="mainContent">
  <input type="text">
  <button id="greeting">クリック</button>
</template>

ボタンがクリックされた際のイベントハンドラを、以下のように記述します。

Template.mainContent.events({
    // Helloボタンのクリックイベント
    'click #greeting': function(event, template) {
        // type属性がtextであるinput要素を取得
        var nameInput = template.find('input[type=text]');
        var name = textInput.value;
        alert('Hello, ' + name);
    }
});

イベントハンドラの第二引数に渡されたtemplateオブジェクトが持つ、findメソッドを使用して、テキストフィールドのDOM要素を取得しています。find以外のメソッドも、使い方は同様です。例えば、上記のテキストフィールドはテンプレート内で最初の要素なので、firstNodeプロパティを使用してDOM要素を取得できます。

var nameInput = template.firstNode;
図3 サンプル6-2の実行結果
図3 サンプル6-2の実行結果

サンプルは以下からダウンロードできます。

まとめ

今回で、Meteorのテンプレートシステムの解説は終わりとします。次回からはいよいよWebアプリケーションのキモとも言える、データベースについて見ていきたいと思います。

おすすめ記事

記事・ニュース一覧