カスタム属性値の参照とHTML要素のネスティング

2015/05/22

前回Cape.JS の紹介として、「Hello, world!」をブラウザに表示する簡単なアプリケーションを作ってみました。

今回は、2つのことを解説します。ひとつは「world」の部分をHTML要素の属性値で置き換える方法、もうひとつはHTML要素をネストさせる方法です。


では、始めましょう。まず、前回作った hello_message1.html をエディタで開いて、ファイル名を hello_message2.html に変更してください。そして、<body> 要素の中身を次のように変更してください。

  <div id="main" data-name="world"></div>
  <script>
    var HelloMessage = Cape.createComponentClass({
      render: function(m) {
        m.p('Hello, ' + this.root.data.name + '!');
      }
    });

    var component = new HelloMessage();
    component.mount('main');
  </script>

このファイルをブラウザで開いてみてください。前回と変わらず、画面の左上に「Hello, world!」と表示されるはずです。

この例では、HelloMessage というコンポーネントをマウントした先の HTML 要素から data-name 属性の値を取得して、仮想 DOM ツリーに埋め込んでいます。コンポーネントの render メソッドの中では this.root で、マウント先の HTML 要素を参照できます。その data プロパティは、HTML5 のカスタムデータ属性(data- で始まる名前を持つ属性)の名前と値を保持する連想配列を返します。

マウント先の HTML 要素は main という id を持つ <div> 要素です。その要素は data-name="world" というカスタムデータ属性を持っています。その値 "world"this.root.data.name で取得できます。ですから、

        m.p('Hello, ' + this.root.data.name + '!');

と書くことにより、ブラウザ上に「Hello, world!」という文字列が現れるのです。

試しに、data-name 要素の値を「ruby」に変えてファイルを保存し、ブラウザをリロードしてみてください。画面表示が「Hello, ruby!」に変化します。


続いて、HTML 要素のネスティング(入れ子)について説明します。

先ほど作成した hello_message2.htmlhello_message3.html に名前を変えて保存し、<head> 要素の末尾に次の行を追加してください。

<link rel="stylesheet"
  href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">

bootstrap の CSS ファイルを取り込んでいます。

そして、<body> 要素の中身を次のように変更してください。

  <div id="main" data-name="world"></div>
  <script>
    var HelloMessage = Cape.createComponentClass({
      render: function(m) {
        m.div({ class: 'container' }, function(m) {
          m.h1('Greetings from Cape.JS');
          m.div({ class: 'panel panel-default' }, function(m) {
            m.div('Hello, ' + this.root.data.name + '!',
              { class: 'panel-body' });
          });
        });
      }
    });

    var component = new HelloMessage();
    component.mount('main');
  </script>

このファイルをブラウザで開くと、次のような画面表示になります。

画面表示

この例では、div メソッドの最後の引数に無名関数を指定することにより HTML 要素のネスティングを行っています。次に示すのは、上記のコードから生成される HTML 文書の断片です:

<div class="container">
  <h1>Greetings from Cape.JS</h1>
  <div class="panel panel-default">
    <div class="panel-body">Hello, world!</div>
  </div>
</div>

div メソッドの最後の引数として指定される無名関数は1個の引数(m)を取ります。この引数は、前回解説したマークアップ・ビルダー(仮想 DOM ツリーを作るためのオブジェクト)です。無名関数の中で仮想 DOM ツリーに加えられた HTML 要素は、無名関数を導入した HTML 要素の「子」要素となります。

上記の例では、無名関数の中でさらに無名関数が呼ばれています。すなわち、2段階のネスティングが行われています。その結果、最も内側の <div> 要素は、最も外側の <div> 要素の「孫」要素となっています。


今回はここまでとしましょう。次回text() メソッドと innerHTML オプションについて解説します。