How to get rails controller variable in js file

2019-05-10 19:29发布

问题:

I have a variable in rails controller like

def index
@approveflag = true
end

I need to access this variable in my javascript code, I used the code given below in index.html.erb

<script>
alert("<%=@approveflag%>")
<script>

It works fine with result "true".But when I moved this code to its corresponding .js file it gives an alert with result string ""<%=@approveflag%>"". What is the reason. How can I solve this?

Thanks in advance.

回答1:

I personally don't like mixing js with erb so I would do something like this:

in index.html.erb

<%= content_tag :div, '', id: 'mycontainer', data: { source: @approveflag } %>

in js

$('#mycontainer').data('source')
alert($('#mycontainer').data('source'))

And you have the value from that instance variable, you can add a data attribute in a link_to if you want.



回答2:

You cannot use the js files for this, they are part of the asset pipeline, they are compiled/compressed, and preferably only downloaded once by your client (browser). So they should not change. So at the time the js-files are precompiled, the instance variable is not set and would not make any sense anyway.

But there are a few options.

You can declare a javascript variable in your view, which your javascript can use (for global data)

Code (I use haml):

:javascript
  var approveFlag = #{@approveflag} ;

You can declare data-tags on elements, if the data belongs to a specific element. But for instance, you could also a data-tag on body element

For instance

%body{:'data-approveflag' => @approveflag}

Or something like

= link_to 'Collapse', '#', 'data-collapse-div' => 'class-to-collapse'

Alternatively you can use ajax/json to download the data. This is clean, but adds an extra delay, so only do this is if the data is not required immediately.



回答3:

I recommend that you to use the 'gon' gem

I'm usually more oriented to straight options that don't imply installing, but trust me using 'gon' is very direct and clean

In your Gemfile add this lines

# To use controller variables as javascript variables
gem 'gon'

Do a bundle install to get/install the gem

In your app/views/layouts/application.html.erb add the following line

<%= include_gon %>

Then in your controller pass your variable to gon as simple as this

gon.your_variable = @controller_variable

And in your javascripts retrieve your variable (in this case to show an alert)

alert (gon.your_variable) ;

And That's it !

For more examples and details see the Wiki page - https://github.com/gazay/gon/wiki



回答4:

In my project I need sometimes user language related translations. So what I did is, I created a simple js file to store the localized text:

var TRANSLATION_ARRAY = []

function store_translation(key, value) {
  TRANSLATION_ARRAY[key] = value
}

function get_translation(key) {
  return TRANSLATION_ARRAY[key]
}

In den index.html.erb or other components I do this to store the localized text:

store_translation('text_id', "<%= translate_with_user_language('text_id') %>")

In my plain js file located in app/assets/javascripts i get the localized text by:

get_translation('text_id')

Works very well. You can use this approach also for other purposes not only translations.