Ruby
Rails
kaminari
0

RailsでHandsOnTableを利用するベストプラクティス

HandsOnTableについて

基本的な使い方はこちらの記事が詳しいです。
https://qiita.com/opengl-8080/items/ac19deec388c357cd498
https://qiita.com/opengl-8080/items/9d25e106ff48b66cb908

Jsでこれだけきっちり動くグリッドコンポーネントは本当に使いやすいです。
今回はコンポーネントをRailsでうまいこと動かすためのプラクティスをいくつか紹介します。

前提条件の説明

今回はAjaxをバリバリ使っているので、まだJquery依存な形で作成していきます。

ページング処理には、Kaminariを利用しています。

Rails5以上推奨です。

yarn使った方が、良いので。

セットアップについては省きます。

yarnで、HansonTable入れたり、モデル作成部分は説明しません。
今回は一例として、ユーザー管理画面の作成としてみます。

まずはコントローラーから

最初の表示用にhtmlを利用し、データの取得には*.erb.jsを利用します。
コントローラー内部でうまく使い分けしています。

こうすることで、1回目の読み込み処理を遅延読み込みにし、初回表示速度を早めています。

Controller(users_contoroller.rb)

*.rb
class UserssController < ApplicationController
  # GET /users
  def index
    respond_to do |format|
      format.html {}
      format.js {
        @users= User.page(params[:page])
      }
    end
  end
end

index.erb.html

*.erb.html
<div id="hot" class="cursor"></div>
<div id="paginator"></div>
<script>
  var hotElement = document.querySelector('#hot');
  var columns = [{  
      title:"ID",
      data: "id",
      readOnly: true,
      type: 'text',
  },{   
      title:"ユーザー名",
      data: "name",
      readOnly: true,
      type: 'text',
  }]
  var hotSettings = {
    data: {},
    columns: columns,
    };
  var hot = new Handsontable(hotElement, hotSettings);

  var loadData = function(){
    $.ajax({type:"GET",url:"/users",dataType:"script"});
  };

  loadData();

</script>

HTMLについて

本来なら、JSを分けるべきですが、一旦同じファイルに記載しています。
Jsにて、HansOnTableのセットアップを行っていますが、この時点で、データは空です。

Ajaxでのデータ読み込み

このajaxでの処理がポイントになります。
dataType:"script"とすることで、index.js.erbに記載したscriptの処理を実行することができます。
この方法は、link_toなどで、remote:trueの処理を書く場合と同じ方法ですね。

View(index.js.erb)

*.js
// URLの書き換え処理
history.replaceState("permit",null,"<%= request.url %>");  

// ページングと、検索条件の表示を更新
$("#paginator").html("<%= j paginate(@user,remote:true) %>");

// Gridデータを更新
hot.loadData(<%= raw ActiveModel::Serializer::CollectionSerializer.new(@user).as_json.to_json %>);

Ajaxからの読み込み処理、index.js.erbを利用したデータ描画を行います。

ここで、hansontableにJson化したUserデータを挿入しています。
加えて、URLの書き換えも行っています。初回読み込み時には必要ありませんが、
ページング処理や、検索条件の変更などがあった場合に使えます。

Kaminariを利用したページングの使い方。

今回はKaminariのデフォルトテンプレートを生かしたまま動作するようにしています。

paginateでHtmlを生成し、そのままDivの中身を差し替えしています。
remote:trueを指定することで、ページング処理から呼ばれるときも、index.js.erbで処理されるため、
レイアウトは更新されず、HandsOnTableの中身と、ページネーションだけ更新されていきます。

この方法を利用して、実運用では、検索条件のテンプレ更新も使っています。
js.erbを利用して、コンポーネントごと差し替えをしていると、Jsが破綻しないので、オススメです。
(turbolinkつかえっていう話もありますが)

まとめ

データをjson読み込んだりするのを非同期処理で書くのは難しいですが、こうしてIndex.js.erbに書くと、可読性が高く、不具合が起きにくい書き方にすることができます。

Paginationがそのままテンプレートとして、利用できるのは大きいですね。
この方法をそのまま利用して、検索条件やページごとの変動項目の書き換えなども可能です。

細かいプラクティスとしては、エラーハンドリングは書かず、別途documentでAjax:errorイベントなどを拾ったり、error.js.erbを作成して、アラートを表示させたりしています。

こうすることで、比較的Jsを書かずに、データの更新処理かけるので、ぜひ利用してみてください。