実践入門 Ember.js

第2回 URLと画面表示(RoutingとTemplates)

この記事を読むのに必要な時間:およそ 7 分

前回はEmber.jsの概要を解説しました。Ember.jsの歴史から今後の展望,そして動作環境を構築して画面の表示ができることまでを示しました。
今回からは簡単なアプリケーションを作成しながら,Ember.jsの構成要素について一つひとつ見ていくことにしましょう。

今回のテーマはRoutingTemplatesです。
なぜこの2つから解説を始めるかというと,RoutingとTemplatesはEmber.jsアプリケーションの入口と出口に相当するものだからです。

今回のゴールは次のようなEmber.jsアプリケーションの仕組みを理解することです。

前準備

さて,さっそくアプリケーションの作成……といきたいところですが,その前に少しだけ前準備をしておきましょう。

前回からのアップデート

前回の記事からのEmber.jsのアップデートについて簡単に解説します。2014年12月8日に新しいバージョンである1.9.0がリリースされました※1)⁠Ember.js 1.9.0では,依存するHandlebarsのバージョンが1.3.0から2.0.0に変更されました。そこで,あらためて環境の準備から始めます※2)⁠

※1
詳しくはEmber.js 1.9.0のリリースノートを参照してください。
※2
Ember.jsはGoogle Chromeと同じようなタイムボックスによるリリースサイクルを採用しているため, 頻繁に新しいバージョンが公開されます。次の安定版である1.10.0は2015年1~2月にリリース予定です。

ファイルの準備

  1. まずはEmber.jsを使うために必要なライブラリをダウンロードします。

  2. HTMLとJavaScriptファイルを作成します。

    index.html

    <!DOCTYPE html>
    <html>
      <head>
        <script src="libs/jquery-2.1.1.min.js"></script>
        <script src="libs/handlebars-v2.0.0.js"></script>
        <script src="libs/ember.js"></script>
        <script src="app.js"></script>
      </head>
      <body>
      </body>
    </html>

    app.js

    App = Ember.Application.create();
  3. 次のディレクトリ構成で配置します。

    .
    ├─⁠─ app.js
    ├─⁠─ index.html
    └─⁠─ libs
        ├─⁠─ ember.js
        ├─⁠─ handlebars-v.2.0.0.js
        └─⁠─ jquery-2.1.1.js

開発ツールのインストール

Ember.jsのデバッグツールであるEmber Inspectorをインストールします。

この拡張を入れると,ブラウザの開発者ツールに"Ember"タブが増えます。

Ember Inspector

画像

このタブでは,Ember.jsアプリケーションのデバッグやパフォーマンスチェックが行えるようになります。詳しい使い方は,今後の連載の中で少しづつ解説していく予定です。

さて,ここまでで前準備が完了しました。

Templates

では,さっそくTemplatesから見ていきましょう。

Ember.jsでは,アプリケーションで表示する画面はHandlebarsと呼ばれるテンプレート言語を用いて記述します※3)⁠HandlebarsはHTML中に式を埋め込む形式のテンプレート言語です。

ただ,JavaScriptの任意の式を記述することはできず,Handlebarsで定義されたヘルパーと描画時に与えたオブジェクトのプロパティのみを記述できます。一見すると不便に感じるかもしれませんが,記述内容を制約することでテンプレートとプレゼンテーションロジックの分離が強制されます。Ember.jsはこの特性を利用して,⁠埋め込まれた値が変化したときに自動で追随する」という仕組みを提供しています。

※3
Ember.js 1.10からはHTMLBarsという Handlebarsの後継のテンプレートに変更される予定です。記述が多少変わりますが大きな変更はありません。1.10がリリースされた際にはあらためて解説します。

ではHandlebarsの記法を見ていくことにしましょう。

先ほど作成したindex.htmlbodyタグの中に次のタグを追加してください。

<script type="text/x-handlebars" data-template-name="index">
  <h1>{{title}}</h1>

  タグ:
  {{#each tag in tags}}
    <span>{{tag}}</span>
  {{/each}}

  {{!これはコメントです}}

  <p>{{body}}</p>

  書いた人: {{author.name}}
  <div {{bind-attr class=status}}>
    {{publishedAt}} 公開
  </div>

  {{#if author.twitter}}
    (@{{author.twitter}})
  {{/if}}

  <hr>
  記事を修正する:
  {{input value=body}}
</script>

また,このテンプレートに表示するためのオブジェクトを用意しましょう。app.jsに次の内容を追記してください。

App.IndexRoute = Ember.Route.extend({
  model: function() {
    var post = {
      title: '実践入門 Ember.js',
      body: 'Ember.jsについて解説します。',
      tags: ['Ember.js', 'JavaScript'],
      status: 'newly',
      publishedAt: '2014年12月23日',
      author: {
        name: '佐藤竜之介',
        twitter: 'tricknotes'
      }
    };
    return post;
  }
});

これは,変数postが参照するオブジェクトをテンプレートに渡すためのコードです(詳細は次項で解説します)⁠

さて,動かしてみると次のような表示になっているはずです。

とくにCSSを入れていないのでとても簡素な見た目ですが,ここにはHandlebarsの基本となる要素が含まれています。では順に説明していきます。

<script type="text/x-handlebars" data-template-name="index">

scriptタグにtype="text/x-handlebars"を指定することで,Ember.jsで使うためのテンプレートであることをEmber.jsに知らせています。また,data-template-nameに指定した値がテンプレートの名前になります※4)⁠Ember.jsがテンプレートを探索する際はこの名前を利用します。

※4
data-template-nameの代わりにidを使うこともできますが,ページ内のIDと重複することを避けるため,本連載ではdata-template-nameを使うことにします。
<h1>{{title}}</h1>

{{から}}で囲まれた部分にはオブジェクトのプロパティやHandlebarsのヘルパーを埋め込むことができます。ここではオブジェクトのプロパティであるtitleを埋め込んで表示しています。

{{#each tag in tags}}...{{/each}}

値が配列の場合,eachヘルパーを使うと要素をひとつひとつ取り出せます。この#/で範囲を指定するヘルパーをHandlebarsの用語では"Block Expressions"と呼びます。

{{!これはコメントです}}

{{!}}の範囲はコメントです。HTMLには描画されません。

{{author.name}}

オブジェクトがネストしている場合,.で深い階層の値を参照できます。

<div {{bind-attr class=status}}>

HTMLの属性を埋め込みたい場合はbind-attrヘルパーを使います。下の例のように属性に{{}}を埋め込んだ場合,エラーになってしまい動作しません。

<div class="{{status}}">

これはEmber.jsが提供するHandlebarsでの値の自動更新の実装上の制約です。

ただ,Ember.js 1.10.0から導入予定のHTMLBarsではこの制約はありませんので,上の例のように属性を直接埋め込んでも動作します。

{{#if author.twitter}}

値の真偽で出力を切り替えられます。通常のJavaScriptと同じく0''(空文字)が偽として評価されるほか,空配列も偽として評価されます。ifの他に,値が偽のときに評価されるunlessもあります。そしてそのどちらもelseが指定可能です。

次の2つの例は同じように評価されます。

{{#if isPublished}}
{{else}}
  (この記事は未公開です)
{{/if}}
{{#unless isPublished}}
  (この記事は未公開です)
{{/if}}
{{#unless isPublished}}
  (この記事は未公開です)
{{/if}}

elseは範囲を取らない{{#else}}~{{/else}}とならない)ことに注意してください。

{{input value=body}}

inputタグを生成するヘルパーです。

value=bodyとすることで,inputタグのvalue属性とオブジェクトのbodyプロパティを結びつけています。これによって,ユーザがテキストフィールドに値を入力することで画面に表示されているbodyも追従して変更されます。このような仕組みを「データバインディング」と呼びます。Ember.jsはデータバインディングを全面的にサポートすることで,アプリケーションから決まりきった画面更新のロジックを排しプログラマの負担を軽減してくれます。

以上,Templatesの簡単な説明でした。

著者プロフィール

佐藤竜之介(さとうりゅうのすけ)

株式会社えにしテック所属。JavaScriptとRubyが好きなウェブ系プログラマ。オープンソースソフトウェアに強い関心がありEmber.jsにも数多くのパッチを送っている。

ブログ:http://tricknotes.hateblo.jp/
Twitter:@tricknotes

コメント

  • craete -> create

    デバッグオプションのAfterの箇所がTypoってます。

    App = Ember.Application.craete({
    (略)
    });
    ではなく
    App = Ember.Application.create({
    (略)
    });
    です。

    コピペして動かないので考えこんでしまいました(笑)

    Commented : #1   (2015/01/02, 19:38)

コメントの記入