のらねこの気まま暮らし

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

FirefoxOSを試してみる 第2回

前提のお話

FirefoxOSを試す
提供されてるサンプルアプリが動いたよ!の続き。

volo serveって・・・rを仲間はずれにするなよ!!

volofileが定義しているコマンドなのでカスタマイズできるらしいのよ。

firefoxos-quick-start/app/volofile

こいつをいじって、serveをserverにしてやる。

serveコマンドの定義

volofileの252行目

    serve: function(d, v, namedArgs) {

serverコマンドに書き換え

    server: function(d, v, namedArgs) {

serverコマンド、いっきまーす!

 (mizuki)$ volo server
starting web server on port 800

grunt.jsで管理したい

grunt-voloなるものがある。

https://github.com/volojs/grunt-volo

gruntのinstallはお済みですか?

$ cd firefoxos-quick-start/app
$ npm install grunt grunt-cli grunt-volo

globalにgruntを入れてたけど、localがどうのこうので動かずだったのでlocalで入れなおした。

Gruntfile.jsにtasksを登録してくださいな

  grunt.loadNpmTasks('grunt-volo');                                                                                                                                      

こいつ・・・動くぞ!

(mizuki)$ grunt volo:serve
Running "volo:serve" (volo) task
starting web server on port 8008

で、テストアプリは動いたのよ。

プロセスが重複しているとevents.jsがコケる(らしい)

ちょっとハマったのでメモ。
下記のエラーは、volo serveを2回連続で呼び出した時に発生するっぽい。
プロセス殺してvolo serveしたらエラーでなかった。

(mizuki)$ volo serve
starting web server on port 8008

events.js:71
        throw arguments[1]; // Unhandled 'error' event
                       ^
Error: listen EADDRINUSE
    at errnoException (net.js:770:11)
    at Server._listen2 (net.js:910:14)
    at listen (net.js:937:10)
    at Server.listen (net.js:986:5)
    at Function.app.listen (/Users/mizuki/project/firefoxos-quick-start/app/node_modules/connect/lib/proto.js:229:24)
    at Object.module.exports.serve [as run] (/Users/mizuki/project/firefoxos-quick-start/app/volofile:279:41)
    at commands.run (/usr/local/share/npm/lib/node_modules/volo/lib/commands.js:154:37)
    at _fulfilled (/usr/local/share/npm/lib/node_modules/volo/node_modules/q/q.js:860:32)
    at resolve.promiseSend.done (/usr/local/share/npm/lib/node_modules/volo/node_modules/q/q.js:881:34)
    at makePromise.promise.promiseSend (/usr/local/share/npm/lib/node_modules/volo/node_modules/q/q.js:553:9)

俺はcoffeeで書くぞジョジョーッ!!

現在volofileをcoffee化してgruntでcompileするようにしようとしている。
次回乞うご期待!!

FirefoxOSを試してみる

まえがきとかそんなものはない

FirefoxOSを試す。
それがたったひとつのシンプルな答え。

FirefoxOSについてぼくが知っていること

  • FirefoxOS持ってません。(世に出ているのかも知らん)
  • FirefoxOS Simuratorなるものがある
  • FirefoxOS simuratorはFirefoxのAdd-onとして提供されている
  • FirefoxOSはJavaScript, CSS, HTMLで構築できる

以上っ!!!!!
※この記事を書くまで、Fire”F"oxだと思ってました。Firefoxです。FFって略し方はおかしい!

なにはともあれFirefox(Desktop)をインストールする

Mac Book AirにはFirefox入ってなかったの。

以下よりインストール。
http://www.mozilla.jp/firefox/

Firefox OS Simurator をインストールする

以下にやり方はまとまってる。(英語)
https://developer.mozilla.org/ja/docs/Mozilla/Firefox_OS/Using_Firefox_OS_Simulator

Add-onは下からインストールできる(上記ドキュメントにもリンクはある)
https://addons.mozilla.org/en-US/firefox/addon/firefox-os-simulator/

Dashbordを開く

[ツール]->[Web開発]->[Firefox OS Simurator]

Simuratorを起動する

[Stopped]っていうトグルっぽいボタンが左っかわにあるのでそいつをクリックしてやる。

開発環境

基本的にnode.jsとvolojsというライブラリを使ってサーバ立ててごにょごにょするっぽい。

node.jsのインストール

さっき書いた。
http://mizuki-r.hatenablog.com/entry/2013/04/24/194255

volojsのインストール

globalにインストールしていいのか?とは思ったけど気にせずドーン

$ npm install -g volo

※path通ってなかったので、/usr/local/share/npm/binにpath通した。

サンプルアプリをチェックアウトしてくる

$ git clone git://github.com/mozilla/firefoxos-quick-start.git
$ cd firefoxos-quick-start/app
$ volo serve
starting web server on port 8008

Simulatorのブラウザを開いてhttp://localhost:8008を叩く

と動く。




今日はここまで!!1

Mac Book Air に node.js を入れる

今の時代、node.jsなしじゃ生きられませんよね。というわけでMac Book Airにnode.js入れる。

前提

  • OSX
  • homebrewインストール済み

node.jsのインストール

$ brew install node
==> Downloading http://nodejs.org/dist/v0.8.18/node-v0.8.18.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/node/0.8.18
==> make install
==> Caveats
Homebrew installed npm.
We recommend prepending the following path to your PATH environment
variable to have npm-installed binaries picked up:
  /usr/local/share/npm/bin
==> Summary
🍺  /usr/local/Cellar/node/0.8.18: 879 files, 14M, built in 3.0 minutes

versions

(mizuki)$ node -v                                                                                                                                                    [~]
v0.8.18
(mizuki)$ npm -v                                                                                                                                                     [~]
1.2.2

Backbone.jsのpopstate時にルートページのcallbackが実行される

Backbone.jsとjQuery pjaxを併用してフロントエンド充してるところで、思わぬ罠にハマったので記録しとく。

問題

var MyRouter = Backbone.Router.extend({
    "events" : {
        ""        : 'home',
        "path/to" : 'fuga'
    },
    "home" : function () {
        console.log('--route:home--');
    },
    "fuga" : function () {
        console.log('--route:fuga--');
    }
});

$(function () {
    var router = new MyRouter();
    Backbone.history.start({"pushState" : true});
});

こういうコードが合った時、以下のような遷移を行うとする。

/ -> /huga/hoge -> /path/to -> (ブラウザバック)

そうすると、次のような関連性でcallbackが行われる。

遷移 URL console.log
/ / --route:home--
/huga/hoge /huga/hoge
/path/to /path/to --route:fuga--
ブラウザバック /huga/hoge --route:home--

callbackを登録してない"/hoge/huga"のパスでhomeのコールバックが呼ばれてしまう。

原因

console.logとかでchrome developerToolを使ってデータの遷移を追ってみた。

backbone.jsでpopstateされてからコールバックが実行されるまでの流れ

  1. popstateのイベントに登録されているのは、Backbone.History.checkUrlメソッド
  2. Backbone.History.checkUrlの中で呼ばれるBackbone.History.loadUrlメソッド呼ばれる
  3. Backbone.loadUrlはBackbone.History.getFragmentからfragmentを受け取り・上書きする
  4. Backbone.loadUrlはgetFragmentで書き換えたfragmentを元にcallbackを選択・実行する

どうやらBackbone.History.loadUrlメソッドがfragmentを書き換えているらしい

1170: var fragment = this.fragment = this.getFragment(fragmentOverride);

this.fragmentにブラウザバックしたときのURLが入っている。
しかし、fragmentOverrideはundefinedが代入されており、それがthis.getFragmentに渡される。

getFragment内でfragmentOverrideが == null だった場合、fragmentを書き換える。
その結果、fragment === ''という判定がくだされ、""のrouteに紐づくhomeのコールバックが実行される。

fragment == null

undefined == null はtrueとして扱われるため、このよくわからない上書きが発生する。
もし、undefinedを許可したくないのであれば(fragment === null)と型を見ればいい。

Backbone.History.getFragmentはundefinedも許容したい。

上記判定を行うとすると、fragment = ''の時だけfragmentの取得が行われる。
しかし、実は""へのアクセス時のfragmentOverrideはundefinedが格納される。

じゃあこうするしか無いな。

if (fragment === null || fragment === undefined)

・・・・あれ? ソレ結局元にもどっただけじゃんか。

解決策

前回に引き続き@が解決策を提案してくれたよ!
提案というか、発見なんだけど。こうすればいいんじゃね?と。

http://stackoverflow.com/questions/6088073/default-routes-in-a-backbone-js-controller

routesに*{なまえ}のrouteを登録するとデフォルトでrouteを設定してくれる。
こいつを設定すると、homeのtrigger実行されなくなる、と。

"routes" : {
    "*path" : "defaultRoute"
}

ためしてみた。

var MyRouter = Backbone.Router.extend({
    "events" : {
        "*path"   : 'defaultRoute', // <- 追加
        ""        : 'home',
        "path/to" : 'fuga'
    },
    "defaultRoute" : function () {
        console.log('--route:default--');
    },
    "home" : function () {
        console.log('--route:home--');
    },
    "fuga" : function () {
        console.log('--route:fuga--');
    }
});

$(function () {
    var router = new MyRouter();
    Backbone.history.start({"pushState" : true});
});

/ -> /huga/hoge -> /path/to -> (ブラウザバック)

遷移 URL console.log
/ / --route:home--
/huga/hoge /huga/hoge --route:default--
/path/to /path/to --route:fuga--
ブラウザバック /huga/hoge --route:default--

本当だ・・・!

なんでかってーと

pushStateがtrueの時、Backbone.History.loadUrlでfragmentからcallbackが該当するものを探しだすんスよ。
その結果がcheckUrlに渡されて、callbackがあるものはtrueを返すが、trueが無かったら今度はHashから探しにいくんすよ。
Hashでもcallbackが見つからなかったら、""が実行されるらしくて。

なんで、全部のrouteにcallbackが登録されていれば、そいつ(defaultRoute)が実行される。

なんてわかりにくい・・・!

結論

routesにdefaultを登録してやれ。

たぶんBackbone.jsはRoutesにすべてのrouteのこーるばっくを登録している前提で組まれているから。


まったく、Backboneのコンセプトは好きだが、コードは好きになれない。


今回もヘルプで助けてくれた@と、JSで困ったらとりあえず質問を投げてアドバイスくれる@にさんくす。

backbone-pjax.jsを書いた

まえおき

  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" : {
            // 
        }
    });
})();

Backboneとjquery.pjaxの相性は悪い

前置き

以前こんな記事を書いた。
http://mizuki-r.hatenablog.com/entry/2013/02/02/150356

Backboneでpjaxの実装書くより、jquery-pjax使ったほうが楽だし利便性いいよね!
なんかよくわかんないバグにハマったけど試行錯誤してたらうごいたよ!
っていう内容。


お ま え は 何 を 言 っ て い る ん だ

試行錯誤しているうちになんか動くようになった。誰か説明してくれ。

実 は 解 決 し て な い。
気のせいか、別のバグでpjaxしてるように見えてしてなかったとかそんなオチ。

試行錯誤云々で動くはずがない

というのは、ソースを見ればわかる。

jquery.pjax

https://github.com/defunkt/jquery-pjax

version 1.5.1から引用

function pjax(options) {
  options = $.extend(true, {}, $.ajaxSettings, pjax.defaults, options)

  // 中略

  if (xhr.readyState > 0) {
    if (options.push && !options.replace) {
      // Cache current container element before replacing it
      cachePush(pjax.state.id, context.clone().contents())

      window.history.pushState(null, "", stripPjaxParam(options.requestUrl))
    }

    fire('pjax:start', [xhr, options])
    fire('pjax:send', [xhr, options])
  }

  return pjax.xhr
}

と、pjaxメソッドの中にベタっと埋め込まれている。

backbone.js

http://backbonejs.org/

version 0.9.10から引用
長いので、Backbone.history.navigateの部分だけ抽出

    navigate: function(fragment, options) {
      if (!History.started) return false;
      if (!options || options === true) options = {trigger: options};
      fragment = this.getFragment(fragment || '');
      if (this.fragment === fragment) return;
      this.fragment = fragment;
      var url = this.root + fragment;

      // If pushState is available, we use it to set the fragment as a real URL.
      if (this._hasPushState) {
        this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);

      // If hash changes haven't been explicitly disabled, update the hash
      // fragment to store history.
      } else if (this._wantsHashChange) {
        this._updateHash(this.location, fragment, options.replace);
        if (this.iframe && (fragment !== this.getFragment(this.getHash(this.iframe)))) {
          // Opening and closing the iframe tricks IE7 and earlier to push a
          // history entry on hash-tag change.  When replace is true, we don't
          // want this.
          if(!options.replace) this.iframe.document.open().close();
          this._updateHash(this.iframe.location, fragment, options.replace);
        }

      // If you've told us that you explicitly don't want fallback hashchange-
      // based history, then `navigate` becomes a page refresh.
      } else {
        return this.location.assign(url);
      }
      if (options.trigger) this.loadUrl(fragment);
    },

BackboneのpushStateは、Backbone.Router.navigateを呼び出すことでpushされる。
navigateはpushStateしつつ、routesに登録したコールバックを実行するため、navigateを使わない、という選択肢は取れない。

Backbone.Router.navigateは、Backbone.history.navigateにエリアス貼ってるだけなのでそっちみればいい。

設定や一部上書き程度でどうにかなるレベルじゃない

どちらも大きなメソッドに埋め込まれているので、仮にどちらかのpushStateを無効にできたとして、それによる弊害の方が大きくなるため、試行錯誤でパラメータ変えたり上書きしたりする程度でこの不具合は潰せない。

Backbone.history.navigateの引数でどうにかできないか

navigateは(fragment, options)を取ってる。fragmentは今回の件に関係ないので省略。
optionsは以下のパターンを想定している

  • trigger: true|false
    • trigger(Router.routesに登録されているコールバック)を呼び出すか
  • replace: tule|false
    • pushStateではなくreplaceStateを使うか

第二引数にオブジェクト({})ではなく真偽値(true|false)を渡すことも可能だが、その場合、triggerのみがtrueになる。

本当に2回pushStateされているのか

Backbone.jsとjquery-pjaxを読み込んだページで、developer toolでhistoryのAPI叩いてみれば一目瞭然。

まとめ

最初の話

BackboneのRouterでtirgger呼び出しつつpjaxしたい。
Backboneは自前でpjax実装しないといけないのでちょっと面倒。
jquery-pjaxを使いたい。

間違った話

設定しだいでBackbone.historyとjquery-pjaxを併用できるよ!

本当の話

Backbone.historyとjquery-pjaxを並行で使おうとすると、pushStateが2回走るため、同じ履歴が2つ登録してしまうという不具合を引き起こす。

当日追記

silversさんがこの問題に対する解決策をあげてくれました。
silvers++

http://ofsilvers.hateblo.jp/entry/backbone-with-jquery-pjax

jquery.pjax x Backbone.js を試す

週末ですね。こんにちわ。

まえおき

前回のエントリで「Knockback.js試すぜ!」みたいなことを言いましたが撤回します。ドキュメント見て止めました。
理由は以下の二点

  • Backbone.js, Knockout.js知識が必要
  • 日本語での資料が少ない

Backbone.js

というわけで、まずはBackbone.jsをためそうじゃないかと。
大本の目的が、pjaxでページ毎の挙動を制御したいっていう要求があったので、じゃあBackbone.jsだろうと。

http://backbonejs.org/

こんてんつ

  • Initialize
  • Routes
  • View
  • history

Initialize

まずはどうすればいいかの話。
必要最小限では、以下の様な組み合わせるになるのかなと。

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script src="/plugin/underscore-1.4.4.min.js"></script>
    <script src="/plugin/backbone-0.9.10.min.js"></script>
    <script src="/plugin/bootstrap2.2.2/bootstrap.min.js"></script>
    <script src="/js/main.js"></script>

jQueryは何はともあれ必要です。
Underscore.jsはBackbone.jsの動作に必要。
Backbone.jsは本体。フルセットです。
デザインを簡略化するためにBootstrapを利用しています。
main.jsに挙動を定義していきます。

Routes

何はともあれ、まずは一番の要求であるページ毎の挙動ですよね。

var myRouter = Backbone.Router.extend({
    "routes" : {
        ''       : 'index',
        "mypage" : 'mypage',
    },
  "index" : function() {
    },
    "mypage" : function() {
    },
});

$(function() {
    var router = new myRpiter();
});

そのうちまとめるとは思いますが、Backbone.jsではオブジェクトの継承にextendメソッドを利用します。
RouterであればBackbone.Routerをextendする。引数にHASH形式でメソッドや初期値等を設定します。

"routes"

HTTP_PATHと動作するメソッドを紐付けています。
shebungを前提として作られているのか、Rootの"/"を省略しています。すなわち、

GET /mypage でアクセスが来たら、myRouter.routes.mypage が呼び出される

actions

ルーティングされて、myRouter.indexが呼び出されたとします。
その時、例えば

GET /?param=value

みたいなリクエストが着ちゃうとコケるようです。

   "routes" : {
       "?param=:value" : 'index',
   },
   "index" : function(value) {
   },

このようにして、置き換えて上げると引数で受け取れるみたいなので、そういう書き方してあげるとよいんではないかと。

instance

new で定義したクラスを呼び出してあげれば、Routingが設定され、リクエストしたパスを見て処理を行なってくれます。
but,このままではpjaxとか使えません。

PJAX

Backbone.jsのRouterにはhistory管理が同梱されていて、簡単にpjaxを実装できるそうです。

以下のような記事を参考にすれば、わりかし簡単にpjaxを実装できると思います。実際出来ました。

http://kennyj-jp.blogspot.jp/2011/07/backbonejspjax.html
http://taiju.hatenablog.com/entry/20120414/1334390163
http://taiju.hatenablog.com/entry/20120414/1334390163

だが私はそれに反論を唱える

重要なのは、Backbone.jsが提供しているのはpushStateとRouter.navigateによるイベント処理だけだということです。

if 非対応ブラウザのでアクセス
if ページのレスポンスに時間がかかる
if 完全なHTMLをレスポンスしてきた
if InternalServerError等の例外

コケたらなにも反応しないボタンになるか、あるいは自前でアレコレと例外処理を用意しなくてはなりません。


・・・・・



ヽ(´Д`ヽ)(/´Д`)/イヤァ~





僕は、jquery.pjaxに甘えたくなりました。

jquery.pjaxとBackbone.jsを連携させることは可能であるか?

https://github.com/defunkt/jquery-pjax

jquery.pjaxはjquery用に書かれたpjaxのpluginです。
pjax処理の周辺でeventをbindしてくれていてhookが非常に簡単。
また、timeoutやlocation.hrefによる遷移などのサポートも充実していて、非常に使い勝手の良いpluginです。

But

jquery.pjaxが良い物なのは、わかる。このブログ開設当初から使っていた。
Backbone.jsはjQueryを使うことに異論を唱えていない。pluginを使ったからどうだということはない。むしろ積極的に使って効率化できるんじゃないかと思う。余談だ。

では何が問題か。
jquery.pjaxもBackbone.Routerもhistoryの操作を行なっている。
重複操作になり得る可能性は無いか?

とりあえず試す

template/layout.html
<script src="/plugin/jquery.pjax.js"></script>
js/main.js
var viewPjax = Backbone.View.extend({
    "events" : {
        "pjax:send"    : 'send',
        "pjax:succes"  : 'success',
        "pjax:complete": 'complete',
        "pjax:timeout" : 'timeout',
    },
    "el" : document,
    "initialize" : function() {
        $(document).pjax('a', pjax_container);
    },
    "send" : function(e) {
        console.log('pjax send');
    },
    "success" : function() {
        cosnole.log('pjax success');
    },
    "complete" : function(e) {
        $('body').trigger('init');
        this._navigate();
        $(window).trigger('load');
    },
    "timeout" : function(e) {
        console.log('pjax timeout');
    },
    "_navigate" : function() {
        window.router.navigate(location.pathname.substr(1), true);
    },
});

$(function(){
    new viewPjax();
    window.router = new myRouter();

    Backbone.history.start({pushState : true});
});

イグザクトリー そのとおりだ

遷移するけど、バックボタンを二回押さないと戻らないという罠にはまった。
おそらくpushStateが二回走っているが為に履歴が重複登録されているんだろうと想定。

対策

試行錯誤しているうちになんか動くようになった。誰か説明してくれ。

var viewPjax = Backbone.View.extend({
    "events" : {
        "pjax:send"    : 'send',
        "pjax:succes"  : 'success',
        "pjax:complete": 'complete',
        "pjax:timeout" : 'timeout',
    },
    "el" : document,
    "initialize" : function() {
        $(document).pjax('a', pjax_container);
    },
    "send" : function(e) {
        console.log('pjax send');
    },
    "success" : function() {
        cosnole.log('pjax success');
    },
    "complete" : function(e) {
        $('body').trigger('init');
        this._navigate();
        $(window).trigger('load');
    },
    "timeout" : function(e) {
        console.log('pjax timeout');
    },
    "_navigate" : function() {
        window.router.navigate(location.pathname.substr(1), {
            "trigger" : true,
            "replace" : true,
        });
    },
});

$(function(){
    new viewPjax();
    window.router = new myRouter();

    Backbone.history.start({pushState : true});
});

まとめ

  • Backbone.jsでRouterによるページ毎の挙動実装ためした
  • Backbone.jsとjquery.pjaxによるpjax実装をためした

いまいち釈然としないものの、ひとまずよくわからないけれどpjax動いてるんだよね。釈然としない。
Backbone.jsについてはちゃんと中身を確認して把握しないと使い物にするには大変だなぁと思いつつ、ここまで実質半日程度だから比較的軽度の勉強で済む予感。大変なのはこれからか。

JSをModelとかViewとかに分離できるのはすごくありがたい。
なにせいままでイベントとロジック祭りで何処に何があるのか非常にわかりにくかった。

今後、Knockbackとかも試して行きたいが、とりあえずBackboneを使い倒せるようになろうと思う。


うおし、尻みよ尻。

2013/03/06追記

この話には続きがあります。

jquery.pjaxとBackbone.jsの並行運用は
そ ん な 簡 単 な 話 じ ゃ な か っ た
http://mizuki-r.hatenablog.com/entry/2013/03/06/093235