非同期通信とは?
こんなのができる仕組みです。
要は、↑のようなページの更新なしで画面をスラスラ処理できる仕組みを非同期通信と言います。
どうしてできるのか
非同期通信の内容を理解するために、クライアント・サーバー通信の方式で対をなす同期通信との対比を書きます。
同期通信
同期通信はデータ通信のリクエストを出してからレスポンスが来るまでほかの処理を行わずにレスポンスを待ち続ける
非同期通信
非同期通信ではレスポンスを待っている間にほかの処理を行える。ほかの処理を行っている際に、レスポンスを受信すると受信処理を実行する。
一言でまとめると、サーバーからのレスポンスを待たずにブラウザで操作できるようにしているからです。
Ajax
これを実現するのがAjaxというエンジンです。エンジンといってもJavaScriptとXMLというテキストデータの組み合わせです。
「Asynchronous JavaScript + XML」という構成要素から成るエンジンなのですが、 これのおかげで非同期通信を実現しています。
参考:
http://wa3.i-3-i.info/word12672.html
コメント投稿の非同期通信
実際のコメント投稿機能を作った際のソースを記載します。
## コメントを表示するviewファイル
<div class ="contents row">
<div class="content_post" style="background-image: url(<%= @tweet.image %>);">
<% if user_signed_in? && current_user.id == @tweet.user_id %>
<div class="more">
<span><%= image_tag 'arrow_top.png' %></span>
<ul class="more_list">
<li>
<%= link_to '削除', "/tweets/#{@tweet.id}", method: :delete %>
</li>
</ul>
</div>
<% end %>
<%= simple_format(@tweet.text) %>
<span class="name">
<a href="/users/<%= @tweet.user.id %>">
<span>投稿者</span><%= @tweet.user.nickname %>
</a>
</span>
</div>
<div class="container">
<% if current_user %>
<%= form_tag("/tweets/#{@tweet.id}/comments", method: :post, id: "new_comment") do %>
<textarea cols="30" name="text" placeholder="コメントする" rows="2" class ="textbox"></textarea>
<input type="submit" value="SENT">
<% end %>
<% end %>
<div class="comments">
<h4><コメント一覧></h4>
<% if @comments %>
<% @comments.each do |comment| %>
<p>
<storng><%= link_to comment.user.nickname, "/users/#{comment.user_id}" %>:</strong>
<%= comment.text %>
</p>
<% end %>
<% end %>
</div>
</div>
</div>
#↓ jbuilderを使って入力データをJSON形式で出力し、JavaScriptに渡す。
json.array! @products do |product|
json.id product.id
json.title product.title
json.image product.image_url
json.detail product.detail
end
class CommentsController < ApplicationController
def create
@comment = Comment.create(text: comment_params[:text], tweet_id: comment_params[:tweet_id], user_id: current_user.id)
#↓respond_toでリクエストされたフォーマットによって処理を分岐
respond_to do |format|
format.html{redirect_to tweet_path(params[:tweet_id])}
format.json
end
end
private
def comment_params
params.permit(:text, :tweet_id)
end
end
// ↓コメントを出力する関数を定義
$(function(){
function buildHTML(comment){
var html = `<p>
<strong>
<a href = /users/${comment.user_id}>${comment.user_name}</a>:
</strong>
${comment.text}
</p>`
return html;
}
// ↓送信ボタンクリック時にイベント発火
$("#new_comment").on("submit",function(e){
//↓e.preventDefaultで送信ボタンクリック時の通信を止める
e.preventDefault();
console.log(this)
// ↓formDataでフォームの情報を取得
var formData = new
FormData(this);
// ↓非同期通信でコメントが保存されるようにする
var url = $(this).attr("action")
$.ajax({
url:url,
type:"POST",
data:formData,
dataType:"json",
processData:false,
contentType:false
})
//↓ 非同期通信成功時に上で定義した関数を実行
.done (function(data){
var html = buildHTML(data);
$(".comments").append(html)
$(".textbox").val("")
})
//↓エラー時の処理
.fail(function(){
alert("error");
})
})
})```
処理の流れ
全体の流れをざっくりまとめると、以下のようになります。
①viewからコメントを送信
②JS上でコメントの送信を中止、JSON形式への変更リクエスト
③Controllerがリクエスト別で処理を分岐(今回はJSON)
④jbuilderがデータをJSONに変換
⑤JSで表示を実行
まとめ
非同期通信とは、ページの更新なしで画面をスラスラ処理できる仕組みである
非同期通信の仕組みとは、サーバーからのレスポンスを待たずにブラウザで操作できるようにしていることである
非同期通信を実現するものは、Ajaxである
Ajaxを使うと、JS上で表示の処理を柔軟に変えられる