読者です 読者をやめる 読者になる 読者になる

のらねこの気まま暮らし

Perlについてとか、創作についてとか、発展途上の自分と向き合う記録。

backbone-pjax.jsを書いた

pjax backbonejs

まえおき

  1. Backbone.jsとpjax使いたいよ!
  2. Backbone.jsだけでpjax実装できるけどjquery-pjaxで至れりつくせりしたいよ!
  3. Backbone.jsとjquery.pjax.jsを同居させるとpushStateを2回しちゃうよ!
  4. /(^o^)\ナンテコッタイ
  5. 解決策↓

Backbone.js × jQuery pjax - しるてく

ここでの話

  • Backbone.js と jquery.pjaxを同じモノとして扱いたい
  • Backbone.Routerと密に連携したい

Backbone.js と jquery.pjaxを同じモノとして扱いたい

  • pjaxもroutingの一部だと思うの役割的に
  • Viewのいたるところで$(document).on('pjax:hoge', ...)するのはコードが散在して保守性下がる
  • Backbone.Routerの一部を上書きする必要がある。pjax用のviewとrouterの双方に依存するのはちょっとキモチワルイ

Backbone.Routerと密に連携したい

  • Backbone.RoutrerはTriggerの実行後にroute:hogeというトリガが発火する
var router  = new MyRouter();
router.on('route:index', function () {
  console.log('ここはホームですよ!');
});
  • but, trigger設定していないとrouteイベントが発火しない
    • ページ共通で走らせたいBeforeDispatchみたいなのはどこでやればいいんだろう?
    • pjax使ってるなら、pjax:complete, pjax:end等選択肢はある。
  • Backbone.Routerのイベントとしてpjaxも連動できたら直感的(?)に実装できるんじゃないだろうか

提案

Backbone.Pjax.js書いた。
https://github.com/rymizuki/backbone-pjax

  • Historyを複製して、上位クラスに影響無いようにした
    • もうちょい突っ込んで改造できるかも
  • Backbone側ではpushStateさせない
    • 前述にあるとおり
  • Backbone.Pjax.Routerをextendして、pjaxのoptionとかをオーバーライドで実装できるように
    • こっちの方がBackbone的にはわかりやすいんじゃないかと
  • routerにpjax系のイベントをbindできるように

追記

Backbone.Pjax.jsのリンクをgistに貼ってたのでgithubに差し替えた

2013/03/30 追記

Backbone.Pjaxのつかいかた

readmodules

<script src="/plugin/jquery-pjax.js"></script>
<script src="/plugin/underscore.js"></script>
<script src="/plugin/backbone.min.js"></script>
<script src="/plugin/backbone.pjax.js"></script>

javascript

(function () {
    "use strict";

    var MyRouter = Backbone.Pjax.extend({
        "pjax" : {
            "container" : '#container', // $.pjaxのcontainerとなる要素を指定してください
            "options" : {               // $.pjaxのoptionを指定してください
                "timeout" : 2000
            }
        },
        "initialize" : function () {
            // pjaxイベントの設定

            if ($.support.pjax) { // ブラウザがpjaxをサポートしているか
                this.pjaxInit(); // $.pjaxの初期化処理
                this.on('pjax:beforeSend', function () { // $.pjaxのbeforeSendのイベントにbindする
                    console.log('pjax before send');
                },this);
                this.on('pjax:end', this.pageInit, this); // $.pjaxのendのイベントにbindする
            }
        },
        // 以降はBackbone.Roterと同様に利用できる
        "routes" : {
            // 
        }
    });
})();