iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 9
1
Modern Web

Ruby礦工的Rails地圖系列 第 9

How to pass the value from controller to javascript

如何從controller傳遞變數到js
今天來談談這個專案中很常見的需求

先講結論,其實有gem可以簡單的實作
但在介紹gem之前,先來講講一般的方法

熟悉rails運作流程就會知道
從網址到畫面,依序是:

URL > route 解析 > controller > view (js & css)

所以假如想要由controller傳遞變數到js
可以先透過html階段,再由js去html取

html實作上有非常多地方可以讓js抓變數
我個人是推薦使用class或data attribute的方式
假如是想傳遞某種狀態,例如:
<div id="main" class="foo baa <%= @status %>" />
全域變數@status由controller準備

def show
    if is_album
        @status = "album"
    end
end

假設內容為頁面型態
這時js可以這樣抓取
$("#main").hasClass("album")
可以得到是否是否為album的判斷

假如是值的傳遞
<div id="main" data-page_type="<%= @status %>" />
取值方法如下:
$("#main").data("page_type")
如果要透過js給值,寫法如下
$("#main").data("page_type", "new_type")
會把後面的值塞到前面的key內,頁面上的html會變更如下
<div id="main" data-page_type="new_type" />

這樣雖然不算是很麻煩,但是如果數量很多
要在頁面上放一堆變數,還是很麻煩
有人為了解決這個問題,寫了一個很方便的的gem
Gem gon - get your Rails variables in your js

Gemfile
gem 'gon'

在共用的html之前引入,例如
app/views/layouts/application.html.erb

<head>
  <title>some title</title>
  <%= Gon::Base.render_data %>
  <!-- include your action js code -->
  ...

如果是Rails 3以前

<head>
  <title>some title</title>
  <%= include_gon %>
  <!-- include your action js code -->
  ...

接著在controller階段,只需要像下面這樣放值

def show
    gon.abc = "abc"
    gon.foo = [1,2,3]
end

在js階段,只要用同名方法就可以直接使用

gon.abc
=> "abc"
gon.foo
=> [1,2,3]

當然,除了字串,數字、陣列等等型態都可以
有沒有覺得瞬間省事很多
上面廢話那麼多是在拖台錢嗎XD

雖然有很多方便的gem可以省力
單身為rails工程師,還是需要知道沒有gem的時候該怎麼做
畢竟有時候會遇到不明原因gem無法支援的情況
我們還是有可能需要手刻

希望大家開發愉快啦!


上一篇
Top 10 common mistake for junior rails developer (6~10)
下一篇
淺談scope -- 常用的條件通通藏在裡面
系列文
Ruby礦工的Rails地圖30

尚未有邦友留言

立即登入留言