年初にbackbone.jsの調査をしていた頃は、ajaxで画面遷移を行うには、fragmentを利用する事しかできませんでした。
しかし0.5以降では、Backbone.Routerを利用する事によって、pjax(HTML5のpushStateを利用した話題のあれ)な画面遷移が出来るになっています。
pjaxについては、こちらをご参照ください。
またgithubのファイルブラウザはpjaxの良例として有名なのでチェックしてみて下さい。
■何処がpjaxなのか?
まずは下記手順を実施後、http://localhost:3000/を閲覧してみましょう。chrome等html5対応ブラウザで確認して下さい。
次にhelpをクリックしてみましょう。
注目すべきなのは、
①URLが変わっている
②画面下部のレンダリング日時が変わっていない。
次にaboutをクリックしてみましょう。helpの時と同じです。
ブラウザの「戻る」ボタンをクリックしてみましょう。
About => Help => Indexに遷移します。「進む」ボタンもいい感じに遷移します。
About => Help => Indexに遷移します。「進む」ボタンもいい感じに遷移します。
次にHelpが画面に表示されている状態で、「F5」を押下してみましょう。
レンダリング日時が変わったはずです。
■説明
ajaxは非同期に(高速に)画面の一部を書き換える技術ですが、ユーザーの利便性の観点から、ブラウザの戻る、進むを利用可能にする必要があります。これまでのajaxでは、#(フラグメント)を利用して実現する事が多かったのですが、あまり良い解決策では有りませんでした。
pjaxでは、HTML5のpushStateを利用する事により、ブラウザのURLを切り替えつつ、画面の一部のみ切り替える事ができます。無論、URLは通常のURLですので、「通常のHTTPリクエスト」として処理するように実装する事が可能です。下記のIndexControllerでは、Ajax通信かどうかでレイアウトの適用を変更しています。
これができたら何が嬉しいのか?!それは読者への宿題にしておきます(^.^;
ちなみに、IE(≒pushStateをサポートしていないブラウザ)でみたら fragment での遷移に自動的に切り替わってました。。
■体験手順
・まずは前回の記事を参考にプロジェクトを生成する。
$ ./gen.sh pjax
・移動して体験に必要なファイルを用意する
$ cd pjax
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>pjax2</title>
<meta charset="utf-8"/>
<%= stylesheet_link_tag :all %>
<%= javascript_include_tag :defaults %>
<%= javascript_include_tag :backbone %>
<script><%= yield :javascripts %></script>
<%= csrf_meta_tag %>
</head>
<body>
<%= content_for?(:content) ? yield(:content) : yield %>
</body>
</html>
app/views/layouts/index.html.erb
<%= content_for :javascripts do %>
$(function() {
var Workspace = Backbone.Router.extend({
routes: {
"": "index",
"help": "help",
"about": "about"
},
index: function() {
$("#app").load("/");
},
help: function() {
$("#app").load("/help");
},
about: function() {
$("#app").load("/about");
}
});
var ws = new Workspace();
Backbone.history.start({pushState: true});
$("#indexButton").click(function() {
ws.navigate("", true);
});
$("#helpButton").click(function() {
ws.navigate("help", true);
});
$("#aboutButton").click(function() {
ws.navigate("about", true);
});
});
<% end %>
<%= content_for :content do %>
<div id="app"></div>
<hr/>
<input type="button" name="index" value="index" id="indexButton" />
<input type="button" name="help" value="help" id="helpButton" />
<input type="button" name="about" value="about" id="aboutButton" />
最終レンダリング日時:<%= I18n.l Time.now %>
<% end %>
<%= render :file => "layouts/application" %>
app/views/index/index.html.erb
<h1>Index</h1>
app/views/index/help.html.erb
<h1>help</h1>
app/views/index/about.html.erb
<h1>about</h1>
app/controllers/index_controller.rb
class IndexController < ApplicationController
layout "index"
def index
render :layout => !request.xhr?
end
def help
render :layout => !request.xhr?
end
def about
render :layout => !request.xhr?
end
end
config/routes.rb
最後に
root :to => "index#index"
match "help" => "index#help"
match "about" => "index#about"
public/index.html <= 削除
サーバ起動!
$ rails server
0 件のコメント:
コメントを投稿