Play!frameworkでpjaxを使ってみた
Play!framework でpjaxを使って見ました。
pushslate とはなんぞや
pjax こそが pushState + Ajax の本命 - punitan (a.k.a. punytan) のメモ
http://d.hatena.ne.jp/punitan/20110404/1301895279
こちらのサイトが大変参考になりました。
要するに
- 非同期通信なんだけど、パーマリンクを持ってて進むとか戻るとかのボタンが使えるよ!
という非常に抽象的な解釈をしておきます。
上記のpunitan 氏のページでは、perlで実装していましたが、
これをPlay!frameworkで上手いことやってみよう!というものです。
pjaxを使えるようにするまで
pjaxを追加する
defunkt/jquery-pjax - GitHub
https://github.com/defunkt/jquery-pjax
からjquery.pjax.jsをダウンロードし、
/public/javascripts
以下に追加しますi
HTMLヘッダー(main.html)
以下の文章を追記。
<script src="@{'/public/javascripts/jquery.pjax.js'}" type="text/javascript" charset="utf-8"></script>
リンク部分(main.html)
イメージとしては何かの一覧がナビにあって、それをクリックすると
詳細の内容を表示するようなページを想定しています。
以下の文章を追記。
<ul> #{list items:hoges ,as:'hoge'} <li><a class="pjax" href="/Application/show/${hoge.id}">PJAX!</a></li> #{/list} </ul> <div id="main"> #{doLayout /} </div>
javascript
$(function(){ $('a.pjax').pjax('#main'); })
routesファイル(conf/routes)
* /Application/show/{id} Application.show
としてやると、アンカーのhrefで指定した結果を#mainに描画してくれます。
java(app/controllers/Application.html)
public static void show(Long id){ //処理内容 render(); }
pjaxとplayのテンプレートをうまいこと使う
RESTfulなアプリケーションを考えた時このままだと、pjaxを使って非同期に読み込むまでは良いとして、このまま更新を行うとpjaxを使って描画した内容しか表示されません。
同じURLだとしても・・・
- 直接アクセスしたらナビゲーションなどの他のHTMLも取ってくる
- pjaxで非同期にアクセスしたらナビゲーションなどのHTMLを取得せず、内容部分だけを描画
というようにしたいはず・・・!
以下のようにしました
show.htmlを作成する
ここでは、show.htmlはmain.htmlを継承して描画する関係になっているとします。
main.htmlはヘッダーとかナビゲーションメニューとかを持っているイメージだと思ってください。普通だとこうなります
#{extends 'main.html' /} その他の内容
pjaxを利用するとヘッダー情報にx-pjax :true という情報が追加されるので、
これがTrueだったら側の部分(main.html)を描画せず、falseだったら描画するような指定の仕方をしてやります
#{ifnot request.headers.containsKey("x-pjax")} #{extends 'main.html' /} #{/ifnot}その他の内容
これで、
- URL直叩き:ヘッダーやナビゲーションメニューも一緒に描画
- pjaxでのアクセス:mainコンテンツのみ描画
というようなことができると思います。