バインディング – Ember.js入門(5)

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Ember.jsの基礎を徹底的に解説するEmber.jsの5回目です。今回はいよいよバインディングについて解説します。内容としては、アクションの基本 - Ember.js入門(4)からの続きとなるため、読んでない方は先にご覧頂くと良いでしょう。

バインディング

Ember.jsの最も特徴的な機能のひとつはバインディング(Binding)です。

Ember.jsのバインディングとは、ModelやControllerのプロパティに対し、Templateの入出力値を結びつける(Bind)する機能です。簡単に言えば、ModelやControllerのプロパティを変更したならば自動的にViewの表示内容が更新されたり、Viewの入力項目に入力を行うと自動的にModelやControllerのプロパティが変更されます。Ember.jsでは、基本的に自動でバインディングが行われるため、MVCアプリケーションにありがちな冗長コードを書く手間がほとんどありません。

それでは、簡単なアプリケーションを作り、バインディングの強力な機能を試してみましょう。

カウントアップを行うEmberアプリケーション

作成するのは、ボタンをクリックするとカウント(数字)が1つインクリメントされるシンプルなアプリケーションです。

バインディング_-_Ember.js

Controllerを定義する

はじめにControllerを定義します。

window.App = Ember.Application.create();
App.ApplicationController = Ember.ObjectController.extend({
  count: 1,
  actions: {
    countUp: function() {
      var current = this.get('count');
      this.set('count', current + 1);
    }
  }
});

ApplicationControllerをObjectControllerを継承して作成し、追加のプロパティとしてcountを定義しました。このcountはControllerが保持するアプリケーションの状態です。Modelを作成して定義することも可能ですが、永続化しない一時的なデータや状態はModelよりもControllerに定義する方が自然な設計です。

次に前回も解説したactionsを定義します。countUpアクションを定義し、イベントハンドラーとなる関数を定義しました。この関数では、countをインクリメントしています。ポイントは、getメソッドとsetメソッドです。

getメソッドとsetメソッド

getメソッドsetメソッドは、Javaのgetter/setterのようなアクセサメソッドです。プロパティ名を指定して、値を取得したり設定します。

これらのメソッドは、object[keyName] や object.keyNameと同じような機能を提供しますが、バインディングの機能と大きく関係します。get/setメソッドを使った場合(主にsetメソッドですが)、そのプロパティを参照しているTemplateなどが自動的に更新されます。内部的には各プロパティにオブザーバが登録されており、各オブザーバに変更が通知され、更新処理が行われます。したがって、Ember.jsではプロパティの取得・設定には必ずget/setメソッドを利用することがポイントです。

ここでは、Controller自身のプロパティcountをgetし、インクリメントした値をsetしています。そして、その後にありがちなViewの再描画処理がありません

Viewを定義する

Viewはとても単純です。

	<script type="text/x-handlebars">
  <h1>Actions</h1>
  <p><button {{action 'countUp'}}>Count Up</button></p>
  <p>Count: {{count}}</p>
	</script>

前回解説したように、countUpアクションを実行するボタンを定義しています。そして、カウントを表示する個所は単純に{{count}}とプロパティ名を記述するだけです。

{{count}}は、対応するControllerのプロパティから値を設定します。そして、自動バインディングが働くため、Controllerのプロパティが変更されると、自動的に再描画されます。この強力な機能があるため、Viewもイベントハンドラーも本来必要な最低限の記述だけで済むのです。

なお、Viewから取得されるプロパティは、はじめにControllerのプロパティが参照されますが、Controllerに対応するプロパティがない場合、自動的に対応するModelからプロパティを検索します。

まとめ

Ember.jsのバインディング機能を使うことで、Viewの再描画などのコードを書く手間がなくなり、アプリケーションで必要な処理の記述に専念できます。ただし、プロパティの設定にはget/setメソッドを使わなければなりません。

Ember__キャンバス_4

なお、Ember.jsのようにMVCでクライアントサイドを構築する場合は、Viewよりも先にControllerを作成する方が自然に構築できると思います。

最後にコード全体を掲載します。

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>バインディング - Ember.js</title>
</head>
<body>
	<script type="text/x-handlebars">
  <h1>Actions</h1>
  <p><button {{action 'countUp'}}>Count Up</button></p>
  <p>Count: {{count}}</p>
	</script>
	<script type="text/javascript" src="js/libs/jquery-1.9.1.js"></script>
	<script type="text/javascript" src="js/libs/handlebars-1.0.0.js"></script>
	<script type="text/javascript" src="js/libs/ember-1.0.0.js"></script>
	<script type="text/javascript">
window.App = Ember.Application.create();
App.ApplicationController = Ember.ObjectController.extend({
  count: 1,
  actions: {
    countUp: function() {
      var current = this.get('count');
      this.set('count', current + 1);
    }
  }
});
	</script>
</body>
</html>

http://emberjs.com/guides/templates/the-application-template/ http://emberjs.com/guides/templates/actions/