今日はTwitterに検索をかけて、返されたJSONデータを、表示に反映するサンプルを見ていきたいと思います。以下がソースコードの全文です。
var App = Ember.Application.create();
var searchTweets = function(query) {
return $.Deferred(function(defer) {
return $.ajax({
url: 'http://search.twitter.com/search.json',
dataType: 'jsonp',
data: {
result_type: 'recent',
rpp: 10,
page: 1,
q: query
}
}).done(function(res) {
return defer.resolve(res.results);
});
}).promise();
};
//// Controllers
App.tweets = Ember.ArrayController.create({
content: [],
update: function(query) {
var _this;
_this = this;
searchTweets(query).done(function(tweets) {
_this.get('content').unshiftObjects(tweets);
});
}
});
//// Views
App.ApplicationView = Ember.View.extend({
query: '#emberjs',
search: function() {
App.tweets.update(this.get('query'));
}
});
App.TweetsView = Ember.View.extend({
templateName: 'tweets-view',
tweetsBinding: 'App.tweets.content'
});
まずControllerから見ていきましょう。
App.tweets = Ember.ArrayController.create({
content: [],
update: function(query) {
var _this;
_this = this;
searchTweets(query).done(function(tweets) {
_this.get('content').unshiftObjects(tweets);
});
}
});
検索結果のツイートを表示するために、Ember.ArrayControllerのインスタンスを作成しています。
ArrayControllerは、contentメンバに配列データを格納します。Ember.jsでは、アプリケーションで扱うデータの格納、ビジネスロジックは、Controllerに置くのが流儀です。(一般的なMVCフレームワークなら、この役割はModelが担うところですが、Ember.jsでは用語がかなり違和感のある使い方をされています。)
updateメソッドは、検索ボタンが押された時に呼ばれます。今回はunshiftObjects()メソッドを利用して、どんどん結果を追加していくようにしました。もし検索ごとに結果を入れ替えたいなら、unshiftObjects()を使う代わりに、set()を使えばOKです。
↓こんな感じです。
searchTweets(query).done(function(tweets) {
_this.set('content', tweets);
});
Ember.jsは、現状データの送信/受信の部分の処理を提供していません。今回は、jQueryの機能を使って検索結果の受信を実装しました。
次はViewを見ていきます。
//// Views
App.ApplicationView = Ember.View.extend({
query: '#emberjs',
search: function() {
App.tweets.update(this.get('query'));
}
});
App.TweetsView = Ember.View.extend({
templateName: 'tweets-view',
tweetsBinding: 'App.tweets.content'
});
Viewは簡単です。ApplicationViewの検索ボタンが押された時のトリガはsearchメソッドです。queryはテキストフィールドにバインディングされていて、ユーザが入力した値で検索を掛けます。結果表示はTweetsViewが行います。
テンプレートの記述は以下のとおりです。
<script type="text/x-handlebars">
{{view Ember.TextField valueBinding="query"}}
<button {{action "search"}}>search tweets</button>
{{view App.TweetsView}}
</script>
<script type="text/x-handlebars" data-template-name="tweets-view">
<ul>
{{#each view.tweets}}
<li>
<a href="http://twitter.com/{{from_user}}">{{from_user}}</a> {{text}}
</li>
{{/each}}
</ul>
</script>
以下のページで実際の動作を確認できます。