バインディング – Ember.js入門(5)
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つインクリメントされるシンプルなアプリケーションです。
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.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/