実践入門 Ember.js

第1回 Ember.jsの世界

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

Ember.jsの特徴

さて,Ember.jsのバックグラウンドについて理解が深まったところで,次はEmber.jsの特徴を解説します。

Ember.jsはRuby on RailsからCoC(Convention over Configuration; 設定より規約)の理念を取り入れており,適切な名前付けを行うことでEmber.js本体が各クラス同士を結びつけアプリケーションを組み立ててくれるようになっています。そのため自明なコードを省略することができ,少ないコードで見通しよくアプリケーションを構築することができます。

Ember.jsの機能

では,Ember.jsの特筆すべき機能を見ていきましょう。

  • Auto updating templates
  • Routing
  • Components

Auto updating templates

Ember.jsではHandlebarsと呼ばれるHTMLに非常に近いテンプレート言語を使って画面を構築します。Handlebarsから生成されたHTMLでは,ユーザからの入力によってデータが変更されるとそのデータを表示している部分すべての表示が自動的に更新されます。この仕組みは双方向バインディングと呼ばれています。

Routing

Ember.jsでは画面にパーマリンクを割り当てることができます。パーマリンクを記録しておけば別のブラウザでアプリケーションを開いても同じ状態で表示することができます。また,別のユーザに特定のメニューを表示する手順を伝える際,"メニュー"->"設定"->"カスタマイズ"のような操作手順を伝えるのではなく,"http://example.com/settings/custom"のようなURLを伝えられる,ということが可能になります。

Components

HTML構造をまとめてひとまとめにして,独自の要素として扱うことができます。ComponentsはHTML構造だけでなく,イベントや内部実装をカプセル化します。例えば「"1分前"や"3日前"などの相対日付を表示するタグ」「ストップウォッチを実現するタグ」を作成して,アプリケーションに埋め込むことができます。これはHTML5で仕様策定が進められているWeb Componentsにインスパイアされて導入された機能で,将来的にはWeb Componentsとの統合も視野に入れられています。

環境準備

さて,それではいよいよ実際にEmber.jsを動かしてみましょう。

  1. Ember.jsと依存ライブラリをダウンロードします。

    本稿執筆時点でのEmber.jsの安定版は1.8.1です※5⁠。

    ダウンロードしたら,これらをlibsディレクトリの下に置きます。

    .
    └── libs
        ├── ember.js
        ├── handlebars-v1.3.0.js
        └── jquery-2.1.1.min.js
  2. ※5
    Ember.js 1.9からはHandlebars 2.0が必要です。依存バージョンは公式サイトに記載されています。
  3. HTMLを用意します。

    index.htmlという名前で次の内容を保存します。

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

    index.htmllibsと同じディレクトリに配置します。

    .
    ├─⁠─ index.html
    └─⁠─ libs
  4. アプリケーションを初期化します。

    app.jsという名前で次の内容を保存します。

    // app.js
    App = Ember.Application.create();

    app.jsindex.htmllibsと同じディレクトリに配置します。

    .
    ├─⁠─ app.js
    ├─⁠─ index.html
    └─⁠─ libs

    index.htmlを編集してbodyタグの次のように書き換えます。

    <body>
      <script src="app.js"></script>
    </body>
  5. Templateを用意します。

    bodyタグの中に,次のコードを追記します。

    <script type="text/x-handlebars">
      <h1>Hi, {{name}}!</h1>
      My name is {{input value=name}}.
    </script>

ここまでで,次のようなファイル構成になっているはずです。

.
├── app.js
├── index.html
└── libs
    ├── ember.js
    ├── handlebars-v.1.3.0.js
    └── jquery-2.1.1.min.js

ではブラウザでindex.htmlを開いてみましょう。テキストフィールドに入力した文字がリアルタイムで画面上に反映される画面が確認できたでしょうか?

nameというプロパティを介して,ユーザからの入力とHTMLへの表示が同期されているのがわかります。これがEmber.jsの機能であるAuto updating templatesです。

次の画面が完成イメージです。

その他の環境構築方法

また,この方法以外にもbowerEmber CLIといったEmber.jsが推奨するビルドツールで環境を構築する方法もあります。詳しくは公式サイトをご参照ください。

また,手軽にEmber.jsを触ってみるというだけでしたらEmber.js用のjsbinを使うという方法もあります。

お好みの方法で環境を構築してください。

Ember.jsの構成要素

ここまでだと,⁠動いているのはわかったんだけど,どうやって動いているのかわからない!」と感じている方が多いのではないでしょうか? それもそのはず,Ember.jsでは明示的に記述しなくてもいい部分が多いため裏側の仕組みがわかりづらいのです。そこで,ここからはEmber.jsの構成要素を紹介しつつEmber.jsが動作している仕組みを解説します。

今まで書いたコードで暗黙的に動いている部分は,明示的に書くこともできます。先ほどのサンプルと同等なアプリケーションを実現しようとすると,次のようなコードになります。

app.js

// Application
App = Ember.Application.create();

// Router
App.Router.map(function() {
  this.resource('index', {path: '/'});
});

// Route
App.IndexRoute = Ember.Route.extend({
  model: function() {
    var you = {name: null};

    return you;
  },
  controllerName: 'index',
  viewName: 'index'
});

// Controller
App.IndexController = Ember.ObjectController.extend({
});

// View
App.IndexView = Ember.View.extend({
  templateName: 'index'
});

また,テンプレートにもdata-templates-name属性を追加します。

index.html

<script type="text/x-handlebars" data-template-name="index">
  <h1>Hi {{name}} from Ember.js</h1>
  My name is {{input value=name}}.
</script>

いきなりコードが増えましたね。では,これらの要素を例に挙げつつEmber.jsの構成についてみてみましょう。

Ember.jsのアーキテクチャ

画像

  • Router … URLとRouteの対応付けを行います。
  • Route … Model, Controller, Viewの紐付けを行います。アプリケーションにパーマリンクを与える場合,その都度Routeを作成します。
  • Model … 画面に表示するモデルです。任意のJavaScriptオブジェクトを使うことができます。
  • Controller … Modelをデコレートして,ユーザからの入力イベントを処理します。また,アプリケーションの内部状態を保持する役割もあります。
  • View … DOMの操作やDOMからのイベントを扱います。
  • Template … Controller, ModelをHTMLに反映します。Handlebarsで記述します。

さきほどのサンプルの場合,URLの入力からHTMLの表示までは次のような流れで処理されます。

  1. App.RouterがURLをもとにApp.IndexRouteをアクティブにする
  2. App.IndexRoutemodelメソッドを実行して,画面に表示するモデルを取得する
  3. App.IndexRoutecontrollerNameプロパティからApp.IndexControllerを見つけ出しインスタンス化する
  4. App.IndexRouteviewNameプロパティからApp.IndexViewを見つけ出しインスタンス化する
  5. App.IndexViewtemplateNameプロパティからdata-template-name="index"のテンプレートを取得して表示に備える
  6. App.IndexRouteはmodel,controller, viewを結びつけ,templateに描画してHTMLを生成する

適切な名前付けによって自明なコードを省略することで,最初に作成したサンプルのようにとてもシンプルに記述することができます。

まとめ

今回はEmber.jsの歴史と特徴を紹介しました。次回からは簡単なアプリケーションを作成しながらEmber.jsの各機能について詳しく解説します。

著者プロフィール

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

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

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