joppot

コピペで絶対動く。説明を妥協しない

railsのgonで別ページでリロード後turbolinksで移動したら変数がundefindする場合の対処

      2016/05/19

Pocket

gon_top_thumb

概要

(追記 2016/05/18

この方法を行うと、turbolinksで問題が起きました。
turbolinksで移動した回数だけ、javascriptが実行されてしまいました。
例えば、
<%= link_to 'Destroy', item, method: :delete, data: { confirm: 'Are you sure?' } %>

というところで、confirmが移動した回数だけ表示されました。
原因はこの記事の

<%= Gon::Base.render_data %>

にあります。gonのscriptのアウトプットをdivで囲うと問題が起こりました。なので、別の方法が思いつくまで、
しばらく、消去線をつけておきます。

(追記 2016/05/19
gonはgithubではapp/views/layouts/application.html.erbに
<%= Gon::Base.render_data %>
を記述するように書いてありますが、これだとturbolinksに対応しません。

今のところ、一番簡単な解決方法はgonの変数を定義しているアクションのviewに
<%= Gon::Base.render_data %>
を書く方法がうまくいきます。

みさなさんこんにちはcandleです。今回は今回はgonを使った場合にgonの値がundefindになってしまう場合の対処です。

実際にやってみると以下のようなエラーが出ます。

例えば、pagesコントローラーのtopアクションで、gonに値を入れます。
gon_value

ここではcoffee scriptで書きますが、こんな感じで、値があれば、コンソールとbodyタグ直下に値を表示するようにします。

gon.testshow

pagesのtopアクションにアクセスすると、以下のように表示されます。
pages_top_show_ok

続いて、別のページにリンクからturbolinksで移動して、ページをリロードして戻ってくると、gon.testに入れた値が未定義になってしまします。

undefined_test_value-1

今回はこちらにあるgithubのissueに上がっている方法を使用しました。

https://github.com/gazay/gon/issues/106

前提

gonが入っている。

SPONSORED LINK


gonの値を正しく読み込む

上記のURL先にもあるように、まずはapp/views/layouts/application.html.erbを開きます。

そしたら、<%= Gon::Base.render_data %>を

で囲います。

<div id="gonvariables">
  <%= Gon::Base.render_data %>
</div>

nest_with_div-1

coffee scriptのファイルを開きます。私はapp/assets/javascripts/pages.coffeeに記述します。

以下を記述します。

gonfix = ->
  eval $('#gonvariables > script').html()
$(document).on 'page:restore', gonfix

fire_gon

このスクリプトはdiv id = #gonvariablesの中にscriptタグがあったら、無理やり実行するというものです。
evalはむやみやたらに使うのは推奨され無いことがあるのですが、Gemが改善されるまでの応急処置として十分ですね。

これで、どこでページリロードして、gon.testが定義されていなくても、私の場合はpagesコントローラーのtopアクションにくると、正しく値がセットされます。

goodvalue-1

まとめ
余談なのですが、私はいつもcoffeeでは

$(document).on ‘ready page:load’, ->
を使用していたのですが、page:loadはturbolinksのリンクをクリックするたびに、内部の処理回数が1つづつ増えていくのですね。
驚きました。
もう少し勉強して、turbolinksの正しい使い方をします。

 - プログラミング , ,