こんにちは
この記事はプログラミングの知識を記録しておく目的で作成しています。
ご興味のある方は是非ご覧ください。
今回のお題は、
実装:非同期通信
そもそもどんなことだったかを知っておきましょう。
非同期通信とは?
送信フォームデータを送信するために送信ボタンを押した際、
ページがリロードされなくても情報が反映される。
例えばこんな様子。
sendボタンでカラーの値を保存して上左端に新しくカラーパネルを追加しています。
※写っていませんがリロードのマークもこれで動いていません。
✔︎その他にも例えば…
・タスク管理アプリ:テキストフォームからタスクを追加→ページがリロードせず追加が表示される
✔︎非同期通信の実装目的は?
ページ遷移せずに一部だけ更新することで、
素早く更新でき、ユーザーが使いやすくなる。
今回実装する際の前提事項
✔︎Ruby、Ruby on Rails
✔︎JavaScript、jQuery
✔︎非同期通信とは?で出てきた例を実装する
→イベント(フォーム送信)の発火をきっかけに、データが保存されてカラー情報が表示される。
✔︎VScode、HTML、HAML、SCSS
非同期通信の実装までの手順を把握して流れを掴む
それではどのように実装していくのか
タスクとして洗い出してみます。
なんとなく、どのような作業がなのか思い出せるようになるといいですね。
①JavaScriptとそのライブラリのjQueryを使用する準備をする。
✔︎jQueryを導入する
→「yarn」インストールする
→Gemを記述
✔︎JavaScriptのファイルを読み込む準備をする。
→JavaScriptファイルを作るためのディレクトリを作成
→そのディレクトリにJavaScriptのファイルを作成
✔︎ビューファイルにJavaScriptのファイルを呼び出せる記述
→application.html.hamlにJavaScriptを呼び出す記述
!!!
%html
%head
%meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/
%title VisualMusic
= csrf_meta_tags
= csp_meta_tag
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
= javascript_include_tag 'application'
%body
= yield
✔︎application.jsのファイルを呼び出せるようにする。
✔︎jQueryを使えるように「require rails-ujs」を記述。
✔︎application.js直下のファイルを読み込めるようにapplication.jsに記述する。
✔︎jQueryが動くか確認する。
→console.logを使用
②フォームが送信されたら発火するようにする。
✔︎フォームにイベントをセット
→from要素を$( )で取得
✔︎デフォルトのフォームを送信する通信により画面遷移するのを阻止
→e.preventDefault( )
✔︎デフォルトを阻止したらJSファイルでコンソールを使用して確認
✔︎ファーム送信(イベント発火)した時、Songcolors#createが動くようにする
→FromDataの取得
→Ajaxでデータを送りたいアクションのパスを記述
→Ajax関数のオプションを設定
③Songcolors#createでメッセージを保存、 respond_toでHTMLで返す時とJSONで返す時の処理を分ける。
✔︎非同期通信でカラーのデータが保存されているか確認
→保存した時ターミナルで「JSON」「COMMIT」になっているか確認。
def create
@songcolor = Songcolor.create(color: params[:color], song_id: params[:song_id])
respond_to do |format|
format.json
end
end
④jbuilderで保存したデータをJSON形式で返す。
✔︎respond_toで分けたのでjbuilderでデータを作成して返す
→create.json.jbuilderを作成して必要なテーブルの情報を渡す。
json.color @songcolor.color
✔︎ターミナルのログでcreate.json.jbuilderが読み込まれているか確認。
→Rendered songcolors/create.json.jbuilderという記載
✔︎binding.pry受け取った値を確認。
⑤返ってきたJSONをdoneメソッドで受け取り、 HTMLで見た目の変更(追加)部分を作成する。
✔︎HTMLを作成する。
→function buildHTML(songcolors){…省略…return html }
✔︎値がdoneで引数として受け取れているかどうかconsole.logで確認もできたらする。
→.done(function(data){let html = buildHTML(data);で受け取れているか。
⑥作成したHTMLを画面のカラーパネル左端の一番上に追加する。
✔︎.prepend指定した要素の最初に、引数で指定した内容を追加。
⑦連続で送信ボタンを押せるようにする。
⑧非同期に失敗した場合の処理をする。
これで完了です!!
詳しい解説を見ながら実装したい人はする
✔︎各項目のリンク先は詳細な解説
「非同期通信の実装までの手順を把握しよう」の各項目に詳しい解説のurlに飛べるようにしているので非同期通信を実装するヒントにすると実装しやすいますのでいので見てみてください。
また、「✔︎マーク」の前にチェックボックス「」をつけていますので、よろしければどこの項目を実装しているのかわかりやすいようにチェックして使用してみてください。ただページを更新すると消えてしまうのでご注意ください。
コードを記述したファイルの全体を見てみる
筆者の書いたコードなので、
記録ようです。
全体が見えると部分でコードを見るのとまた違って見えるので公開します。
//上は省略
gem 'devise'
#ユーザー管理のため
gem 'jquery-rails'
gem 'pry-rails'
#binding.pry使えるgem
!!!
%html
%head
%meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/
%title VisualMusic
= csrf_meta_tags
= csp_meta_tag
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
= javascript_include_tag 'application'
%body
= yield
※説明時「①JavaScriptとそのライブラリのjQueryを使用する準備をする。」に載せているコードと同じです。
//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css
//= require jquery
//= require rails-ujs
//= require_tree .
$(function() {
function buildHTML(songcolor){
let html =
`<li class="color-box" style="background-color:${songcolor.color}"></li>`
return html;
};
$('.js-form').on('submit', function(e) {
e.preventDefault()
let formData = new FormData(this);
let url = $(this).attr('action');
$.ajax({
url: url,
type: "POST",
data: formData,
dataType: 'json',
processData: false,
contentType: false
})
.done(function(data){
let html = buildHTML(data);
$('.colorForm__submit').prop('disabled', false)
$('.left-box__colors-fild').prepend(html);
})
.fail(function() {
alert('error');
});
});
});
class SongcolorsController < ApplicationController
before_action :set_song
def index
@songcolor = Songcolor.new
@songcolors = Songcolor.where(song_id: @song).order("created_at DESC")
end
def new
end
def create
@songcolor = Songcolor.create(color: params[:color], song_id: params[:song_id])
respond_to do |format|
format.json
end
end
private
def songcolor_params
params.permit(:color)
end
def set_song
@song = Song.find(params[:song_id])
end
end
json.color @songcolor.color
参考ページ
解説リンク先Qiita
*jQueryの導入(HTML)
*API(非同期通信を実装する場合)
*JavaScriptのライブラリJQueryでイベント発火・Ajax(非同期通信を実装する場合)