Ajax on jQuery
jQueryでAjax処理を書くと以下のような感じになります。
<input type="textbox" id="sample" />
<script>
$(function() {
$('#sample').on('change', function() {
$.ajax({
type: 'POST',
url: '/funds/set_category',
data: { category: $(this).val,
dataType: 'json'
}).done(function(data, textStatus, jqXHR) {
// 成功時の処理
}).fail(function(jqXHR, textStatus, errorThrown) {
// 失敗時の処理
}).always(function() {
// 結果にかかわらず実行される処理
});
});
});
</script>
Ajax通信を開始する処理にメソッドチェーンで成功時の処理や失敗時の処理を付け足していきます。
成功時の処理や失敗時の処理を書いていくと、JavaScriptの部分がどんどん肥大化していくことになります。
Ajax on Rails
Railsでは以下のように書くことができます。
<%= text_field_tag 'sample', data: { remote: true,
method: 'POST',
url: set_sample_path } %>
<script>
document.body.addEventListener('ajax:success', function(event) {
// 成功時の処理
});
document.body.addEventListener('ajax:error', function(event) {
// 失敗時の処理
});
document.body.addEventListener('ajax:complete', function(event) {
// 結果にかかわらず実行される処理
});
</script>
少しすっきりした気がします。
data-remote
をtrue
に変更し、他のパラメーターもdata-***
で指定します。
Rubyの処理内なのでurlの指定にはset_sample_path
みたいな変数がそのまま使えます。
また、コントローラーに渡すデータは、テキストボックスならvalue
属性が、セレクトボックスならselected option
が自動的に設定されます。
その他のデータを渡したい場合、data { params: 'id=' + @sample.id, type: 'json' }
のような感じで設定すればOK。
ひとつ注意があります。
例ではページ内にAjax処理を行う場所がひとつだけなので、結果を受け取る処理もひとつだけで大丈夫です。
しかし、Ajax処理を行う場所が複数あると、処理の種類によって結果を受け取る処理を変えなければなりません。
具体的な方法については次のセクションで説明します。
Controller
def set_sample
# データ更新などの処理
result = {
event: 'sample',
data: ...
}
render json: result, status: 200
end
データとステータスコードを返却します。
このとき、データの中にどの処理かが識別できる情報を入れておきます。例ではevent: 'sample'
の部分です。
また、ステータスコードを設定しないとビューでの受信時にデータの形がおかしくなるので必ず設定します。
Re:View
<script>
document.body.addEventListener('ajax:success', function(event) {
// 成功時の処理
var data = event.detail[0];
switch(data.event) {
'sample':
// 処理
break;
...
}
});
...
</script>
再びビューの処理です。
コントローラー側から受信した返却データはevent.detail[0]
の中に入っています。
さらに今回はJSON形式でevent
というパラメーターを設定しているので、event.detail[0].event
で処理が識別できます。
しまった、event
とevent
でevent
がかぶってしまった。
ページ内に複数のAjax処理があるとswitch
などを使って受信処理を分岐させる必要があります。
しかし失敗時の処理は分岐させる必要がないなど、状況に応じて共通化させることもできます。
余談
最近、Napstablookという保有投資信託管理サービスをリリースしました。
本記事はNapstablookの開発中にAjax処理が必要になったため、調べてまとめたものになります。
Napstablookではセレクトボックスやテキストボックスが変更されたときにAjax通信を開始し、コントローラーでデータの更新や計算を行った後、ビューにデータを返すという処理を行っています。
さらに余談
AUTOVICEという私のポートフォリオサイトでRailsの技術情報の記事を書いていますので、よければこちらもご覧ください。
そろそろ独自ドメインに移行したい。