拡張子「.js」の場合は、RJSでレスポンスする
前編の「コントローラからビューの呼び出し」のところで解説しましたが、Railsは同じアクションメソッドでも、リクエスト時の拡張子によって、レスポンスする際の、テンプレートをHTML用やJavaScript用に切り替えができます(注釈)。
注釈:respond_toメソッドは拡張子指定がない場合は、HTTPリクエストヘッダの「Accept」ヘッダの値に従って描画するテンプレートを判定します。Rails 2.1.0からは、Acceptヘッダで「text/javascript」を最優先にしているため、拡張子「.js」を付けなくともRJSテンプレートがあれば、それが描画に使われます(参考:ActionPackのCHANGELOG)。
先ほどのlink_to_remoteでは、Ajaxによるリクエスト先URLを以下のように、これまでのリンク先に「.js」という拡張子を付けたものに変更しています。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
CategoriesControllerのshow()アクションメソッド内のrespond_to()メソッド呼び出し部分も、次のように変更します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
RailsはJavaScriptのレスポンスを要求される場合は、RJSで記述されたテンプレートを使用します。
RJSテンプレートを作成する
RJSテンプレートファイルを以下のパスに作成します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
RJSファイルの内容は次のようにしました。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
RJSコードの解説
RJSテンプレート内では、JavaScriptGeneratorクラスの「page」という名前のインスタンスが利用可能で、このインスタンスに対して、「JavaScriptGenerator::GeneratorMethods」のページにあるメソッドが利用可能です。
「page[:category_name]」は、[ ]メソッドの呼び出しを行う記述で、「$('category_name');」に置き換わります([ ]メソッドのリファレンス)。
「JavaScriptGenerator::GeneratorMethods」にある各種メソッドはメソッドチェーンを利用できるので、以下のように、つないでreplace_htmlメソッドの呼び出しができます。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
replace_htmlメソッドは、DOM要素のinnerHTMLを与えられた引数の値で置き換えるメソッドです(参考:replace_htmlメソッドのリファレンス)。
これにより、以下のようなJavaScriptコードが生成されます。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
これに合わせて、show.html.erbの<h1>や<div>にid値を設定し、「$("category_name")」で正しく参照できるようにします。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
RJSが返すレスポンスをWebブラウザで確認
RJSが返すレスポンスをWebブラウザで直接見てみましょう。URLは以下です。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
次のような内容が表示されます(実際には、日本語部分はエンコードされています)。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
これがクライアント側のeval()関数で実行されます。
生成されたコードのeval()での実行
link_to_remote()が生成したprototype.jsのAjax.Requestは、「evalScripts:true」が指定されていました。これにより、サーバがRJSで生成したJavaScriptコードがクライアント側で自動的にeval()で実行されます。
これで、カテゴリ名、カテゴリ説明文がAjaxで切り替わります。
コラム 「RJSで利用可能なメソッド」
「JavaScriptGenerator::GeneratorMethods」では、[ ]やreplace_htmlのほかにも、さまざまなメソッドがあります。ここでは一部を紹介します。
メソッド | 概要 |
---|---|
replace | 要素も含めた置き換え |
insert_html、remove | DOM要素の挿入・削除 |
show、hide、toggle | DOM要素の表示、非表示 |
select | CSSパターンでの要素検索 |
draggable、drop_receiving | DOM要素のドラッグ&ドロップを有効化 |
delay | setTimeout()による遅延実行 |
call | 任意のJavaScript関数の呼び出し |
≪ | 任意のJavaScript文の実行 |
redirect_to | window.location.hrefによる画面遷移 |
visual_effect | script.aculo.usのEffectの生成 |
literal | JavaScriptリテラル表現を返す |
表 RJSで利用可能なメソッド |
デザインを適用したデモを確認してみる
ここまでのサンプルに、次の変更を行いデザインに適用します。
- スタイルシートを更新。それに伴う画像追加
- show.html.erbのカテゴリ名、カテゴリ説明文を「〜」で囲む
- EditリンクやBackリンクを削除
RJSで、楽しいエフェクトを掛けよう
次にカテゴリ名、カテゴリ説明文の切り替え時にAppearエフェクトを掛けてみます。カテゴリ名の変更部分を次のように修正しました。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
これにより、次のJavaScriptが生成されます。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
visual_effect()メソッドは、script.aculo.usによってElementオブジェクトに追加されたメソッドで、指定された名前のEffectを生成できます(参考:visual_effectのリファレンス)。
これで、カテゴリ名、説明文を一度に更新してAppearエフェクトを掛けることができました。
Copyright © ITmedia, Inc. All Rights Reserved.