今日、複雑なJavaScriptアプリケーションはいたるところで見かけるようになりました。 これらのアプリケーションがより複雑になるにつれ、jQueryコールバックステートメントの長い文字列や、アプリケーションのさまざまな箇所で実行される異なる関数呼び出しは受け入れられなくなってきました。 このため、JavaScript の開発者は、従来のソフトウェア プログラマーが何十年も前から知っていたこと、つまり、整理整頓と効率化が重要であり、アプリケーションのパフォーマンスに大きな影響を与えることを学ぶようになりました。
整理整頓と効率化を達成するために最もよく使われるアーキテクチャパターンの1つは、Model View Controllerと呼ばれるものです。 このパターンはアプリケーションの異なる部分をより管理しやすいかたまりに分割することを開発者に促します。 データベースを直接呼び出す関数を使う代わりに、データベースを管理するモデルを作ることができます。 出力や論理文でいっぱいの HTML ファイルを使用する代わりに、シンプルなテンプレートや View を使用することで、表示コードをシンプルにすることができます。 最後に、Controller はアプリケーションの流れを管理し、さまざまな断片が互いに効率的に通信できるようにします。 アプリケーションでこのパターンを使うと、新しい機能を追加しやすくなります。
近年のインターネットを利用したソフトウェア開発の爆発的な普及に伴い、Ember.js、Backbone.js、Knockout.js、Spine.js、Batman.js、Angular.jsといったMVCフレームワークが目まぐるしく登場しています。 これらのライブラリはJavaScriptで記述され、JavaScript開発のために設計されているため、一方では初級者から中級者までの開発者のギャップを補完し、他方では筋金入りのプログラマーをサポートします。JavaScriptで書かれ、JavaScript開発のために設計されたこれらのライブラリは、一方では初心者や中級者の開発者、他方では筋金入りのプログラマーとのギャップを埋めています。 これらのライブラリは、さまざまなスキルレベルの開発者のニーズを満たすために、幅広い機能と特徴を提供します。
このチュートリアルでは、Ember.js を使って Twitter のタイムラインビューアを作成します。
Ember.js入門
Ember.jsは、JavaScriptフレームワークパッケージの最新メンバーの1つです。 元々は2007年に作成されたSproutCoreプロジェクトから発展したもので、AppleはMobileMeを含む様々なウェブアプリケーションで幅広く使用しています。 emberjs.com、Emberは "プロトタイプを排除し、標準的なアプリケーションアーキテクチャを提供する大規模なWebアプリケーションを作成するためのJavaScriptフレームワーク "と説明されています。 Handlebarsと呼ばれる独自のテンプレートエンジンと緊密に統合されており、Emberの最も強力な機能の1つである双方向データバインディングを提供します。 Emberはまた、状態管理、テンプレートの自動更新、計算されたプロパティなどの他の機能も提供します。 1年間の堅実な開発の結果、Emberは強力なプレイヤーになりました。
Emberの依存関係はjQueryのみです。 EmberアプリケーションのHTMLセットアップのサンプルは以下のコードのようになります。 jQuery と Ember の両方が CDN から更新されることに注意してください。 これにより、これらのファイルを必要とする別のサイトに以前アクセスした際に、すでにこれらのファイルをダウンロードしていた場合、ユーザーのページ読み込みが高速化されます。
<html> 
<head> 
<script src="http://..com/ajax/libs/jquery/..1/..js">
</script> 
<script src="http://..com/downloads/emberjs/.js/ember-....js">
</script> 
<script src="js/app.js">
</script> 
</head> 
<body> 
</body>
 </html> 
MVCの定義
このチュートリアルを続けるにあたり、MVCをより明確に定義しておくとよいでしょう。 このコンセプトは1979年から存在しており、それ以来、モデルのさまざまなバリエーションが存在しています。 最も一般的なプロセスは、通常次のようなものです:
- ユーザーは、キーボードを叩いたり、マウスのボタンをクリックするなどのアクションを実行します。
- コントローラは入力を受け取り、モデルへのメッセージをトリガーします。
- モデルはメッセージに基づいてその内容を変更します。
- ビューはモデルの変更を監視し、それに応じてユーザーインターフェースを更新します。
MVCパターンがどのように機能するかを理解することで、アプリケーションのフローをより簡単にすることができます。 さらに、コードが異なるチャンクに分割されているため、開発者チームはより簡単に、お互いに干渉することなく共同作業を行うことができます。
EmberがMVCを実装する方法
JavaScriptは柔軟で強力な言語ですが、欠点もあります。 MVCスタイルの開発に適した、すぐに使える機能を提供していないのです。 そこで、Emberはベースとなる言語を拡張し、多くの機能を追加しました。 Emberアプリケーションを構築する際には、アプリケーション、モデル、ビュー、コントローラの4つの主要コンポーネントを使用します。 次のセクションでは、これらの各コンポーネントについて説明します。
アプリケーション
Emberアプリケーションには必ずEmber.Applicationのインスタンスが必要です。これは残りのすべてのコードの基盤となり、名前空間と同様に便利な機能を提供します。 Emberアプリケーションの定義は簡単です:
Songs = Ember.Application.create({ mixmaster: 'Andy' }); 
このコードではSongsというアプリケーションを定義し、mixmasterというプロパティにAndyを設定しています。 アプリケーションの名前は好きなものに変更できますが、Ember ではバインディングシステムが見つけられるように、変数名は大文字で始まる必要があります。 アプリケーションを作成する際に追加できる組み込みオプションは他にもあり、好きなプロパティやメソッドを追加することができますが、初心者の方にとって一番気になるのはready()メソッドでしょう。 このメソッドは、jQueryのdocument.ready()ブロックとまったく同じように動作し、次のような方法で実装できます:
Songs = Ember.Application.create({ mixmaster: 'Andy', totalReviews: 0, ready: function(){ alert('Ember sings helloooooooooo!'); } }); 
Models
アプリケーションはデータがなければ意味がありません。 EmberはModelを使って、開発者がデータを構造的に管理できるようにします。 Ember Modelsはデータを保持するだけでなく、その中のデータをモデル化します。 つまり、MP3コレクションに関する情報を保存したい場合、モデルにはtitle属性、artist属性、genre属性などが含まれます。 モデルは以下のようになります:
Songs.Song = Ember.Object.extend({ title: null, artist: null, genre: null, listens: 0 }); 
これらのコードには、他にも注意すべき点がいくつかあります。
- アプリケーションが使用している名前空間がすぐにわかります。 Songsはアプリケーションの名前で、Songはモデルの名前です。
- オブジェクトを拡張する場合、このモデルの将来のインスタンスのための青写真を作成することになります。 これはすべての曲のベースとなるメインオブジェクトなので、大文字を使用します。 このような命名規則により、将来、あなたが使用しているオブジェクトの種類を区別しやすくなります。
- モデルを作成する際に、各属性のデフォルト値を指定することができます。 title、artist、genre属性は後で埋めることができるので、nullとしてマークされています。 listen属性のデフォルト値は0で、その値は音楽コレクションを聴くにつれて増えていきます。
これでSongモデルが整ったので、最初の曲を追加することができます。 Songモデルの初期化にはextendを使いましたが、インスタンスの追加にはcreateを使います。 こんな感じです:
mySong = Song.create({ title: 'Son of the Morning', artist: 'Oh, Sleeper', genre: 'Screamo' }); 
変数が大文字で始まっていないことに注意してください。これはSongモデルのインスタンスだからです。 新しいSongはSongs名前空間にもありません。 アプリケーションでモデルのインスタンスを作成する必要はほとんどありません。 しかし一般的には、モデルのインスタンスは ArrayController のような、似たようなオブジェクトの大きなコレクションの中に置くことになるでしょう。
#p#
ビュー
EmberアプリケーションやMVCスタイルのアプリケーションでは、Viewはユーザーが見て対話できるコンポーネントです。 インラインテンプレートは、生の HTML をページに直接追加することで定義できます。 このテンプレートは script タグに含まれます。 コンテンツを表示したいページ上の任意の場所に追加できます。
<script type="text/x-handlebars"> Hello <b>{{Songs.mixmaster}}</b> </script> 
スクリプトタグは text/x-handlebars 型であることに注意してください。 これは、ページが読み込まれたときにEmberが何かを取得するためのものです。 Emberは、このscriptタグに含まれるHTMLをアプリケーションで使用できるように自動的に準備します。 これらのコードをアプリケーションに配置すると、以下のテキストが表示されます:
Hello <b>Andy</b> 
続ける前に、もう少し深く潜ってみましょう。 ブラウザで太字のテキストを右クリックし、ブラウザの開発者ツールを使って調べてみてください。 いくつかの追加要素に気づくかもしれません。 基本属性が変更されたときに、HTMLのどの部分を更新すべきかを知るために、HandlebarsはユニークなIDを持つタグ要素を挿入します:
<b> <script id="metamorph-0-start" type="text/x-placeholder"></script> Andy <script id="metamorph-0-end" type="text/x-placeholder"></script> </b> 
JavaScriptで直接ビューを定義し、ビューヘルパーを使ってページに表示することができます。 Emberには、アプリケーション内で単純なdivタグを作成するための汎用的なビューがありますが、テキスト入力ボックス、チェックボックス、選択リストなどの基本的なコントロールを構築するためのビューもあらかじめパッケージ化されています。 まずは JavaScript ファイルでシンプルな TextArea ビューを定義します。
Songs.ReviewTextArea = Ember.TextArea.extend({ placeholder: 'Enter your review' }); 
次に、そのビュー用の変数を含む view という単語で始まるパスを参照して、それをページに表示します。 以下のコードを実行すると、TextAreaフィールドがプレースホルダ・テキスト "Enter your review "でブラウザに表示されます。 定義の追加属性としてrowsとcolを指定することもできます。
<script type="text/x-handlebars"> {{view Songs.ReviewTextArea}} </script> 
ハンドル
Handlebarsはテンプレートエンジンであり、開発者が生のHTMLとHandlebars式を混ぜることで、レンダリングされたHTMLを生成することができます。式は {{ で始まり }} で終わります。 前述したように、全てのテンプレートは text/x-handlebars タイプのスクリプトタグの中に置かなければなりません。
デフォルトでは、ハンドルバーに含まれる値は、その値にバインドされていると言われています。 これは、アプリケーション内の他のアクションによって値が変更された場合、ユーザーに表示される値も更新されることを意味します。 次のコードを考えてみましょう:
<script type="text/x-handlebars"> My songs have {{Songs.totalReviews}} reviews. </script> 
アプリケーションが最初に初期化されたとき、ユーザーには以下のテキストが表示されます。
My songs have 0 reviews. 
しかし、データバインディングにより、Songs.totalReviewsの更新によりレビューが追加されると、この値はリアルタイムで変化します。
<script type="text/x-handlebars"> {{#if Songs.totalReviews}} Read all my reviews! {{else}} There are no reviews right now. {{/if}} </script> 
アプリケーションのライフサイクルのどの時点でも、Songs.totalReviewsの値が変われば、ビューは更新され、メッセージの別の部分が表示されます。 また、#と/のシンボルは、この特定のビュー・ヘルパーがクロージャ・マーカーを持っていることをHandlebarsに伝えるために存在しているだけであることも注目に値します。
コントローラー
以前は、Modelは開発者がデータを管理するための手段と定義されていました。 これは事実ですが、狭い定義です。 Modelには、例えば曲や人など、1つのものに関連するデータしか含まれません。 Emberでは、ArrayControllerを使用して、曲、人、部品など、複数のグループを管理できます。 各ArrayControllerには、データを格納する組み込みのcontentプロパティがあります。 このデータは単純な文字列でも、配列やオブジェクトのような複雑な値でも構いません。 さらに、ArrayController には関数が組み込まれており、 それを使用して ArrayController 内のデータを操作することができます。 Song コレクション用の ArrayController はどのようなものになるでしょうか?
Songs.songsController = Ember.ArrayController.create({ content: [], init: function(){ // create an instance of the Song model var song = Songs.Song.create({ title: 'Son of the Morning', artist: 'Oh, Sleeper', genre: 'Screamo' }); this.pushObject(song); } }); 
init関数は必須ではありませんが、songsControllerが準備でき次第init関数をトリガーするので便利です。 この関数は、既存のデータをコントローラに投入するために使用できます。この例では、Ember のデータバインディングを実証するために、コントローラに曲を追加するために使用します。 ArrayController定義と以下のインラインテンプレートを追加し、ブラウザでコードを実行します:
<script type="text/x-handlebars"> {{#each Songs.songsController}} <h3>{{title}}</h3> <p>{{artist}} - {{genre}}</p> {{/each}} </script> 
Handlebarsの各ヘルパーは、データブロックへのパスを受け取り、それをループします。 eachブロックの中でコントローラの各項目と一致するものはすべてページに表示されます。 コンテンツ配列への直接のパスは指定しないことに注意してください。出力されるHTMLは以下のようになります:
<h3>Son of the Morning</h3> <p>Oh, Sleeper - Screamo</p> 
完全統合:EmberTweets
ここまでで、Emberとは何か、Emberで何ができるのかが理解できたと思います。また、Emberを構成する各コンポーネント(アプリケーション、モデル、ビュー、コントローラ)についても理解しているはずです。 次は、この知識を応用して、実際に使えるアプリケーションを書いてみましょう。 このチュートリアルでは、Twitter のタイムラインビューアを作成します。 コードを書く前に、最終的な結果を見ておくとよいでしょう。
#p#
サンプルファイルの作成
この記事の冒頭にあるサンプルHTMLページを使って、まずベースとなるHTMLを構築します。 以下のコードをコピーして、index.htmlという新しいHTMLファイルに貼り付けます。この記事のサンプルファイルにあるCSSファイルを参照する必要があります。 サンプルファイルには、このプロジェクトの出発点も含まれていますので、いつでも使用することができます。
<!doctype html> <html> 
<head> 
<title>Tweets</title> 
<meta name="viewport" content="width=device-width, initial-scale=1.0"> 
<link rel="stylesheet" href="styles.css"> 
<script src="http://..com/ajax/libs/jquery/..1/..js"></script> 
<script src="http://..com/downloads/emberjs/.js/ember-....js"></script> 
<script src="app.js"></script> 
</head> 
<body> 
<script type="text/x-handlebars"> 
<div id="frm"> <b>Load Tweets for: </b> </div>
<div id="content"> 
<div id="recent">
 <h3>Recent Users</h3> 
</div> 
<div id="tweets"> <h3>Tweets</h3> </div> 
</div>
 </script>
 </body>
 </html> 
このアプリケーションには、Twitterのユーザー名を入力する入力フィールド、選択したTwitterユーザーのツイートを表示するタイムライン・ビューア、過去の検索結果を保存する最新ユーザーのリストの3つの部分があることがわかります。
検索ボックスはページの上部に、最新のユーザーは左側の列に、ツイート自体はページの右側の大部分を占めるように表示されます。
/************************** * Application **************************/ 
/************************** * Models **************************/ 
/************************** * Views **************************/ 
/************************** * Controllers **************************/ 
Ember.Applicationの代わりにEm.Applicationを使用していることに注意してください。Em "を使用したい場合はどこでも "Ember "を使用できます。
App = Em.Application.create(); 
Ember.Applicationの代わりにEm.Applicationを使用していることに注意してください。Em "を使用したい場合はどこでも "Ember "を使用できます。
App.SearchTextField = Em.TextField.extend({ insertNewline: function(){ App.tweetsController.loadTweets(); } }); 
このブロックでは、まずApp名前空間を使用し、Emberのプリパッケージビューの1つであるTextFieldを拡張します。 View内で任意のプロパティや関数を使用できることに加え、Emberには組み込みのヘルパー関数も用意されています。 insertNewLine()関数がそれです。カーソルが入力ボックスにあり、ユーザーがキーボードのEnter/Returnを押すたびに実行されます。
型板の作成
TextFieldビューを定義したので、適切なビューヘルパーコードをHTMLファイルに追加します。 index.htmlを開き、"Load Tweets for "という行の直後に以下のコードを追加します。 や }} 内のコードはテンプレートであり、Ember がデータを出力するために使用することを覚えておいてください。 また、view で始まるテンプレートは、JavaScript コードですでに定義されているビューを指します。
{{view App.SearchTextField placeholder="Twitter username" valueBinding="App.tweetsController.username"}} <button {{action "loadTweets" target="App.tweetsController"}}>Go!</button> 
テンプレートのこの部分にはビューヘルパーと {{action}} ヘルパーを持つボタンタグが含まれています。 TextFieldビューSearchTextFieldはHTML5のテキスト入力フィールドに組み込まれた属性であるplaceholderテキストで始まります。 フィールドが空の場合、placeholder属性のテキストが入力フィールドに入ります。 誰かが入力を始めると、その値は消えます。 Emberでは、組み込みのビューでHTML 5標準の属性を使用できます。
2つ目のプロパティは、Emberデータバインディングの機能を強調します。 Emberは、何を達成したいのかを判断するために、一連の規約を使用します。 Binding "という単語で終わるビューのプロパティは、その前にあるプロパティのバインディングを自動的に設定します。 この例では、EmberはApp.tweetsController.usernameの値を入力フィールドのvalueプロパティにバインドします。 変数の内容が変更されると、入力フィールドの値が自動的に更新されます。
{action}}は、入力ドリブン要素への機能追加を簡単にします。 アクション名とターゲットの2つのオプションがあります。 これらは合わせて、Ember オブジェクトに含まれる関数への「パス」を形成します。 上記のボタンの例では、App.tweetsController.loadTweets() が「パス」となり、ユーザーがテキストフィールドで Enter キーを押すと同じ関数が呼び出されます。 ブラウザでindex.htmlを読み込み、Submitボタンをクリックするか、入力フィールドでEnterキーを押します。 ブラウザのコンソールを見ると、エラーが表示されます。 これはApp.tweetsControllerが定義されていないからです。
Tweetストレージオブジェクトの準備
App.tweetsController = Em.ArrayController.create({ c
ontent: [], username: '', loadTweets: function() { 
var me = this; var username = me.get("username"); 
alert(username); 
if ( username ) { 
var url = 'http://..com/1/statuses/user_.json' url += '?screen_name=%@&callback=?'.fmt(.get("username")); 
// push username to recent user array App.recentUsersController.addUser(username); 
} } }); 
loadTweets関数の定義をよく見てください。見慣れないコードがあります。 最初の行は、関数の残りの部分を . App.tweetsController 定義では、範囲またははすべてのEmberオブジェクトの現在の関数で、この場合は. しかし、このチュートリアルの後半でloadTweets関数にさらに機能を追加することができます。 現在のスコープを設定することで、Emberが使用しているコンテキストを理解しやすくなります。
前述したように、Emberはアプリケーションを書きやすくするために、get()やset()などのヘルパー関数を提供しています。 この2つの関数はすべてのEmberオブジェクトに組み込まれており、任意のプロパティや関数に素早くアクセスできます。 App.tweetsController 次の行では、現在のオブジェクトの範囲である , を使用し、get() 関数を呼び出して、値が欲しいプロパティの名前を渡します。 冒頭で使おうとしているユーザー名の値がどこから来ているのか不思議に思うかもしれません。 Emberのデータバインディングは双方向であることを覚えておいてください。 App.tweetsController つまり、入力フィールドに値を入力すると、その入力フィールドビューの valueBinding プロパティがオブジェクトを値で更新します。
ユーザー名が取得されると、それがnullでないことを確認するためのテストが実行されます。 この時点ではifブロックに2つのステートメントしかありませんが、これは後で変更します。 最初のステートメントでは、TwitterのJSONファイルのURLをユーザーに設定しています。 ここではすぐに特別なことに気づかないかもしれませんが、もう少しよく見ると、最後に%@と.fmt()があります。 .fmt()関数は、トークンとして%@を使用して、便利な文字列置換を実行します。 このアプリケーションの設計では検索リストを保存する必要があるので、何らかの方法で検索語を保存する必要があります。 App.recentUsersController 最後の行は関数を実行し、ユーザー名の値を ArrayController にプッシュします。 このコードを実行すると、オブジェクトがまだ存在しないためエラーが発生します。
#p#
保存された検索
次のセクションでは、最近の検索を保存するためのオブジェクトを作成します。 App.tweetsController 以下のコードを使用し、オブジェクトの後に追加します。
App.recentUsersController = Em.ArrayController.create({ 
content: [], addUser: function(name) { 
if ( this.contains(name) ) 
this.removeObject(name);
 this.pushObject(name); }, removeUser: function(view)
{ this.removeObject(view.context); }, searchAgain:
 function(view){ App.tweetsController.set('username', view.context); App.tweetsController.loadTweets(); },
 reverse: function(){ return this.toArray().reverse(); }.property('@each') }); 
ArrayControllerを作成して空の配列の中身を追加する方法はすでにおなじみですが、このオブジェクトにはaddUser関数で始まる新しい要素がいくつかあります。 これは contains() という Ember 組み込みの関数を使って既存の配列を調べます。 結果が見つかったら、ArrayController の関数 removeObject() を使って削除します。 この関数とは対照的に、pushObject()という関数があり、これは個々のオブジェクトをコンテンツ配列に追加するために使用されます。 これらの関数には、複数のオブジェクトを扱う複数のバージョン、pushObjects() と removeObjects() があります。 このコードでは、同じ検索語が何度も表示されないように、検索語を追加する前に既存の検索語を削除します。 コンテンツ配列からオブジェクトを削除する方法がわかったところで、 removeUser()関数の唯一の新しい要素は引数です。 action}}ヘルパーで関数を呼び出すとき、Emberは暗黙的に現在のビューへの参照を渡します。 App.tweetsControllerの例では、ビューはコンテキストを持っています。 このコンテキストは、配列から選択されたアイテムを削除するために使用されます。
searchAgain()関数は現在のビューも引数にとります。 ユーザーが検索された単語をクリックすると、この関数はApp.tweetsController.usernameに選択されたユーザー名を入力し、loadTweets()関数をトリガーして前回の検索結果をワンクリックで表示します。
表示される検索
検索結果を保存したら、次はそれをページに表示しましょう。 以下のテンプレートをコピーして、「最近のユーザー」と書かれたh3タグの後ろに追加してください。
<ol> {{#each App.recentUsersController.reverse}} <li> <a href="#" title="view again" {{action "searchAgain" target="App.recentUsersController"}}>{{this}}</a> - <a href="#" title="remove" {{action "removeUser" target="App.recentUsersController"}}>X</a> </li> {{/each}} </ol> 
もうこのコード全てに慣れているはずです。 App.recentUsersController eachブロックがcontent配列を指し、その中に含まれるHTMLが変数内の各項目に適用されます。 明示的にcontent配列を指す必要はありませんが、この場合、コードは逆順にデータを提供するreverse関数を指しています。 action}}ヘルパーは、ユーザーが各アンカータグをクリックして、指定された関数をトリガーできるようにします。 あまりなじみがないかもしれませんが、唯一の要素は{{this}}です。 コンテンツ配列をトラバースするとき、Emberは現在のインデックスへの参照を{{this}}変数に格納します。 各項目の値は単なる文字列なので、{{this}}を使って現在の項目の値を直接出力することができます。 recentUsersController Twitterのユーザー名をクリックすると、そのユーザーのツイートを再度読み込みます。
ツイート読み込み中
App.Tweet = Em.Object.extend({ avatar: null, screen_name: null, text: null, date: null }); 
App.recentUsersController.addUser(username); app.jsの ; という行を探し、その直後に次のコードを追加します:
$.getJSON(url,function(data){ me.set('content', []); $(data).each(function(index,value){ var t = App.Tweet.create({ avatar: value.user.profile_image_url, screen_name: value.user.screen_name, text: value.text, date: value.created_at }); me.pushObject(t); }) }); 
jQueryを使ったことがある人なら、データを取得するために.get()関数を使ったことがあるでしょう。 .getJSON()関数は同じことを行いますが、JSONパッケージを結果として扱う点が異なります。 さらに、返されたJSON文字列を受け取り、実行可能なJavaScriptコードに変換します。 データが取得されると、コンテンツ配列が空になり、既存のツイートがすべて削除されます。 次の行では、データのパケットを抽出してjQueryオブジェクトにカプセル化し、.each()メソッドで生成されたツイートをループします。 eachブロックでは、ツイートモデルのコピーにデータが入力され、そのデータがにプッシュされます。
最後に、以下の表示コードをindex.htmlに追加する必要があります。コピーして、「Tweet」とラベル付けされたh3タグの直後に貼り付けてください。
<ul> {{#each App.tweetsController}} <li> <img {{bindAttr src="avatar"}} /> <span>{{date}}</span> <h3>{{screen_name}}</h3> <p>{{text}}</p> </li> {{/each}} </ul> 
Emberは純粋な{{Handlebars}}を使ってデータを簡単にページに出力できますが、キャッチがあります。 Emberがスクリプトマークアップで出力値をラップする方法を覚えていますか? HTML属性を使用する場合、それはオプションではありません。 そこでEmberは{{bindAttr}}ヘルパーを提供します。 このヘルパーの中に配置された属性は通常通り出力されますが、バインディングは残ります。 続けて、アプリケーションを実行してみましょう。 ユーザー名を入力すると、ツイートが表示されます。
次はどこを読むべきか
この記事では、Ember.js の機能の基本を学びました。 また、モデル、ビュー、コントローラ、そしてもちろんアプリケーションオブジェクトを使用して、Ember がどのように MVC を実装しているかを学びました。 Handlebars を使用して、ビューヘルパーとアクションヘルパーを持つテンプレートを作成しました。 Model を使ってデータのブループリントを作成し、Controller を使ってデータをコレクションに格納し、View を使ってデータをページに表示する方法を学びました。 最後に、Ember を使用して、データバインディング、計算プロパティ、テンプレートの自動更新を備えた完全なアプリケーションを構築しました。 お母さんもきっと誇りに思うでしょう!




