この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Ember.js入門の6回目は条件句、いわゆるifとかunlessです。それほど難しい話題でもないのでサクサクといきましょう。
バインディングと条件句
Ember.jsでは他のテンプレートエンジンと同様にModelやControllerのプロパティを参照し、特定のタグを表示したり、しなかったりする制御を行うことができます。Ember.jsでは、さらに特徴的な機能があり、条件句の判定値も自動的にバインディングされ、変更されると自動的に再描画されます。
開いて閉じるアプリケーション
今回作成するアプリケーションは、ボタンをクリックするとリストが展開され、Closeボタンが表示されるアプリケーションです。Closeボタンをクリックすると最初の状態に戻ります。
Controllerを実装する
前回と同様に、Controllerを定義して、プロパティとアクションを定義します。
window.App = Ember.Application.create();
App.ApplicationController = Ember.ObjectController.extend({
expanded: false,
actions: {
expand: function() {
this.set('expanded', true);
},
collapse: function() {
this.set('expanded', false);
}
}
});
アプリケーションの状態
アプリケーションには、リストが展開されている状態と展開されていない状態があります。これをControllerのexpandedプロパティに真偽値として定義しました。
アクションの定義
アクションは、リストを展開するアクション(expand
)と、閉じるアクション(collapse
)のふたつを定義します。それぞれのイベントハンドラーでは、expanded
プロパティを設定しているだけです。リストに対して、hide
メソッドなどを実行していないことがポイントです。
Viewを定義する
Viewの定義方法は幾つかあると思いますが、今回は最も単純な記法で、リストが展開している状態としていない状態の両方を定義し、{{if}}
ヘルパーを利用して表示を切り替えました。
<h1>Conditionals</h1>
{{#if expanded}}
<div>
<ul>
<li>Spring MVC</li>
<li>Grails</li>
<li>Ruby on Rails</li>
</ul>
<span style="background:#004;color:#FFF;padding:4px;" {{action 'collapse'}}>Close</span>
</div>
{{else}}
<div>
<span style="background:#008;color:#FFF;padding:4px;" {{action 'expand'}}>Show list</span>
</div>
{{/if}}
{{#if}}
と{{/if}}
が対応している件はかなりキモイですが、タグが対応しているというイメージです。{{else}}も含まれていてさらにキモイですが、あくまでViewの表示ロジックでしかない点、これ以上の複雑な条件を設定しないようにして我慢しましょう。なお、マスコットキャラもキモイです。
expanded
の初期値はfalse
なので、レンダリング結果は、期待するようにelse句側となります。
なお、{{action}}ヘルパーにはbuttonだけではなく、このようにdivやspanタグなども利用できます。
アクションによる自動更新
実際に実行し、Show listをクリックしてみると、リストが展開されCloseが表示されます。つまり、expanded
プロパティが更新された(setメソッドを使います)ことをトリガーとしてテンプレートの再描画が行われています。Ember.jsを利用しない場合は、updateUIメソッドなどを作成し、各コンポーネントをhideしたりshowしたりとしなければいけませんが、Ember.jsを利用すればこんな簡単な記述で実現出来るのです。
勿論、Closeすれば最初の状態に戻ります。
条件句の補足
{{if}}
ヘルパーだけでなく{{unless}}
ヘルパーもあるので、条件となるプロパティが偽の場合も同様に利用できます。また、条件となるプロパティは真偽値だけではなく、オブジェクトや配列でも利用できます。オブジェクトの場合はnull
の時に偽、配列の場合はサイズが0の時に偽として動作します。
{{#unless items}}
<p>カートの商品は空です。</p>
{{/unless}}
まとめ
Ember.jsの自動バインディングは条件句にも適用されます。このため、条件句で表示するHTMLを切り替えるコードは簡単に実装できます。
最後にコード全体を掲載します。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>条件句 - Ember.js</title>
</head>
<body>
<script type="text/x-handlebars">
<h1>Conditionals</h1>
{{#if expanded}}
<div>
<ul>
<li>Spring MVC</li>
<li>Grails</li>
<li>Ruby on Rails</li>
</ul>
<span style="background:#004;color:#FFF;padding:4px;" {{action 'collapse'}}>Close</span>
</div>
{{else}}
<div>
<span style="background:#008;color:#FFF;padding:4px;" {{action 'expand'}}>Show list</span>
</div>
{{/if}}
</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({
expanded: false,
actions: {
expand: function() {
this.set('expanded', true);
},
collapse: function() {
this.set('expanded', false);
}
}
});
</script>
</body>
</html>
http://emberjs.com/guides/templates/conditionals/