自分が jQuery Mobile と Backbone.js を組み合わせて使うときって、jQuery Mobile のデザインやウィジェットが使いたいだけで、ルーティングは Backbone.js でやりたいのがほとんど。
例えば List/Detail タイプのアプリを作っていて、URL に含まれている id によって表示する内容を変えたい場合、Backbone.js の Router を使うとキレイに実装できる。でも、普通に jQuery Mobile と Backbone.js を使っていると、リンクをクリックしたとき jQuery Mobile のページ移動処理が優先されてしまう。
じゃあ、Backbone.js のルーティングを使ってページ移動するにはどうすればいいかっていうと、jQuery Mobile の設定をいじってルーティングを無効にすればいい。身も蓋もないね。
<!DOCTYPE html> <html> <head> <title>jQueryMobile+Backbone</title> <link rel="stylesheet" href="jquery.mobile-1.0.1.css" /> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="underscore.js"></script> <script type="text/javascript" src="backbone.js"></script> <script type="text/javascript"> // jQuery Mobile の設定を行うためのイベントハンドラを登録する。 // jQuery Mobile を読み込む前に登録しないと呼び出されない。 $(document).bind("mobileinit", function() { $.mobile.ajaxEnabled = false; $.mobile.linkBindingEnabled = false; $.mobile.hashListeningEnabled = false; $.mobile.pushStateEnabled = false; }); </script> <script type="text/javascript" src="jquery.mobile-1.0.1.js"></script> </head> <body> <div id="list" data-role="page"> <div data-role="header"> <h1>List</h1> </div> <div data-role="content"> <ul data-role="listview"> </ul> </div> </div> <div id="detail" data-role="page"> <div data-role="header"> <h1>Detail</h1> </div> <div data-role="content"> </div> </div> <script type="text/javascript"> var Entry = Backbone.Model.extend({ defaults: { title: "", body: "" } }); var EntryCollection = Backbone.Collection.extend({ model: Entry }); // エントリ一覧を表示するビュー var ListView = Backbone.View.extend({ el: "#list", render: function() { var $ul = this.$el.find("ul"); $ul.empty(); this.collection.each(function(entry) { var view = new EntryView({ model: entry }); view.render(); $ul.append(view.el); }, this); // リストビューを再描画 $ul.listview("refresh"); return this; } }); // エントリ一覧の各エントリを表示するビュー var EntryView = Backbone.View.extend({ tagName: "li", template: _.template("<a href='#entries/<%= cid %>'><%= title %></a>"), render: function() { var ctx = this.model.toJSON(); ctx.cid = this.model.cid; var html = this.template(ctx); this.$el.html(html); return this; } }); // エントリの詳細を表示するビュー var DetailView = Backbone.View.extend({ el: "#detail", render: function() { this.$el.find("h1").html(this.model.get("title")); this.$el.find("div[data-role=content]").html(this.model.get("body")); return this; } }); // アプリケーションのルーター。 // エントリポイントも兼ねている。 var AppRouter = Backbone.Router.extend({ // ルーティングを定義。 routes: { "": "showList", "entries/:cid": "showDetail" }, // ルーターを初期化。 // テストデータを作成し、最初のページ(=一覧ページ)を表示。 initialize: function() { this.entries = new EntryCollection(); this.entries.add(new Entry({ title: "Foo", body: "Hoge" })); this.entries.add(new Entry({ title: "Bar", body: "Fuga" })); this.detailView = new DetailView(); this.listView = new ListView({ collection: this.entries }); this.listView.render(); }, // $.mobile.changePage を使ってページを切り返る。 // ロケーションハッシュは変更しない。 changePage: function(view, isBack) { if (_.isUndefined(isBack)) { isBack = false; } view.render(); $.mobile.changePage(view.$el, { changeHash: false, reverse: isBack }); }, // 一覧ページを表示。 showList: function() { this.changePage(this.listView, true); }, // 詳細ページを表示。 showDetail: function(cid) { var entry = this.entries.getByCid(cid); this.detailView.model = entry; this.changePage(this.detailView); } }); // ルーティング開始。 $(function() { window.router = new AppRouter(); Backbone.history.start(); }); </script> </body> </html>