2011.08.24 yossy a.k.a. 会長
はいどうも~。Japanese Schoolgirlsが好きなエンジニアの吉田です。
以前「jQuery.tmpl() で HTML の View と Model を分離してみるよ」という
記事を書きましたが、引き続きJavaScriptによるMVCシリーズ第二弾!
今回は、Backbone.jsでViewとModelを分離させてみるという試みです。
ここ最近、JavaScriptのMVCライブラリだと「JavaScriptMVC」や「Knockout.js」
「Backbone.js」などがぼちぼちと知名度を挙げてきているような印象です。
(※注)正確にはKnockout.jsはMVCではなくMVVM(Model-View-ViewModel)ですね。
そんな中SoundCloudなどでも使用されているBackbone.jsがとても気になって
いたので、どのような感じで利用できるのか試してみました。
ちなみに、Backbone.jsは有名どころだと以下のサイトで採用されているようです。
SoundCloud Mobile
LinkedIn Mobile
Basecamp Mobile
Groupon Now!
というわけで、早速Backbone.jsと戯れてみましょう!
・・・と、その前に、Backbone.jsの全体的な仕組みの把握が必要ですね。
Backbone.jsは、一言で説明するとクライアントサイドJavaScriptのMVCフレームワークという位置づけです。
(フレームワークというほど大がかりなものではないかもしれませんが。)
なんとなくGoogle Maps V3のMVC Objectに雰囲気が似ている感じがします。
Backbone.jsの大まかな仕組みを把握するために、主要となる概念を確認してみましょう。
Backbone.jsでは「モデル」「ビュー」「イベント」という3つの主要な概念が存在します。
イベント駆動なアプリケーション開発経験があれば、なんとなくイメージがつくでしょうか。
「モデル」はデータ操作を担当し、データの生成、バリデーション、破棄、
サーバサイドへのデータ保存などを行うことが可能です。
「モデル」のデータが変更された場合は「イベント」が発行され「ビュー」へ
通知される仕組みになっています。
「ビュー」はUIを担当し、「モデル」からの「イベント」を受け取ったのち、
「モデル」のデータを描画することが可能です。
なお、描画の際は、DOMから"id"属性を指定してHTMLを手動で更新する必要はありません。
「モデル」が変更された際に「ビュー」が自動的にそれらの表示を更新します。
backbone.jsを読み込むとすぐに使用可能です。以下のサイトからダウンロードできます。
http://documentcloud.github.com/backbone/
なお、Underscore.jsも必要なのでこちらも以下のサイトからダウンロードしてください。
http://documentcloud.github.com/underscore/
※Underscore.jsはJSでRubyっぽいメソッドなどが使えるようになるユーティリティライブラリです。
今回もjsdo.itを使ってTwitterAPIから検索して表示させることにしてみましょう。
ボタンクリックでTwitterからデータを取得して、「モデル」にツイートデータをぶちこむようにし、
あとは「ビュー」にお任せして表示を更新させてみます。
ちなみに、BackboneのViewではDOMセレクタとしてjQueryやZepto.jsと一緒に組み合わせることが
できますが、今回はjQueryを使います。テンプレートエンジンも前回同様jQuery.tmpl()です。
※JSのテンプレートエンジンは最近だとICanHaz.jsなどでもいいかもしれませんね。
クラスの構造の方針は、以下のような感じで考えてみます。
・TweetModelクラス:個々のツイートのデータを扱う「モデル」
・TweetCollectionクラス:上記ツイートのコレクションの「モデル」
・TweetView:個々のツイートの「ビュー」
・ApplicationModelクラス:アプリケーションで使用する「モデル」
・ApplicationViewクラス:アプリケーションの「ビュー」
// ツイートのモデル var TweetModel = Backbone.Model.extend({ initialize: function () { this.set({ domId: 'tweet_' + this.cid }) } });
// ツイートのコレクション var TweetCollection = Backbone.Collection.extend({ model: TweetModel, });
// ツイートのビュー var TweetView = Backbone.View.extend({ render: function () { this.el = $("#tweetTemplate").tmpl( this.model.toJSON(), this ); return this; }, time_ago: function(time){ var ints = { second: 1, minute: 60, hour: 3600, day: 86400, week: 604800, month: 2592000, year: 31536000 }; time = +new Date(time); var gap = ((+new Date()) - time) / 1000, amount, measure; for (var i in ints) { if (gap > ints[i]) { measure = i; } } amount = gap / ints[measure]; amount = gap > ints.day ? (Math.round(amount * 100) / 100) : Math.round(amount); amount += ' ' + measure + (amount > 1 ? 's' : '') + ' ago'; return amount || 0; } });
// アプリケーションのモデル var ApplicationModel = Backbone.Model.extend({ initialize: function () { this.tweets = new TweetCollection(); } });
// アプリケーションのビュー var ApplicationView = Backbone.View.extend({ initialize: function () { this.model.tweets.bind('add', this.addTweet); this.model.tweets.bind('remove', this.removeTweet); }, render: function () { this.el = $( "#tweetContainer" ); return this; }, addTweet: function (tweet) { var tModel = new TweetModel(tweet); var tView = new TweetView({model: tModel}); this.render().el.append(tView.render().el); }, removeTweet: function (tweet) { $('#' + tweet.get('domId')).remove(); } });
// アプリケーションの実行
(function(){ var appModel = new ApplicationModel({}); appView = new ApplicationView({model: appModel}); })();
appView.addTweet(result);
Backbone.js を使ってTwitterから検索 - jsdo.it - share JavaScript, HTML5 and CSS
Backbone.jsを使うことで、ModelとViewをより疎結合にすることができました。
しかし、今回のサンプルでもわかるように、コードの量がそれなりに増えてしまうため、
規模の小さいアプリケーションには適していないのではないかと考えています。
JavaScriptでMVC構造を綺麗に保った状態でアプリケーションを開発する手法は
まだまだ情報が乏しいような容共なので、模索していく余地がありそうですね。
今回のサンプルプログラムもBackboneのとても簡単な使い方しかしていないので、
もっといいプログラムの書き方があると思います。
なので、参考程度にとどめて頂けると幸いです。
Building a single page app with Backbone.js, underscore.js and jQuery
http://andyet.net/blog/2010/oct/29/building-a-single-page-app-with-backbonejs-undersc/
なお、護身のため補足しておきますが、冒頭で述べたJapanese Schoolgirlsは
そういう趣味なわけではなく、Suspect 44というアーティストのJapanese Schoolgirls
というTranceの曲名なので、白い目で見ないでくださいね。。。
デワデワ。