Ruby on Rails – 将JavaScript变量从控制器发送到外部Javascript资产文件

我正在Ruby on Rails中创建一个网站。 我有一个控制器动作,呈现如下视图:

def show time_left = Time.now.to_i - 3.hours.to_i @character = current_user.characters.find(params[:id]) respond_to do |format| format.html # show.html.erb format.xml { render :xml => @character } end end 

这很好,因为它可以像我一样呈现show.html.erb。 但是我想以某种方式将time_left作为Javascript变量传递给视图,因为这个值被倒计时JQuery插件使用。

我可以在HTML中的页面上放置一个javascript块,然后像这样打印一个实例变量:

  $('#countdown').countdown('') 

但是我想把我所有的JS保存在一个外部文件中,在页面之外,任何人都可以提供一些关于如何实现它的建议吗?

是的你可以!

用一个参数(timelimit)将JS代码重写为函数,并将其放入一些外部文件中。 然后,您可以从视图中调用该函数,并将该@timeleft变量作为JS函数参数传递。

简短的例子:

 #controller @time_left = Time.now.to_i - 3.hours.to_i 

 #javascript function count_down(time_left) { $('#countdown').countdown(time_left) } 

 #view <%=javascript_tag "count_down(#{@time_left})" -%> 

javascript_tag

未经测试的示例,只是想法不完整的解决方案。 不要忘记加载该JS文件。 您可以使用其他JS rails helper javascript_include_tag 。

retro的使用函数参数的技术是可能的,但你必须正确地使用escape_javascriptto_json + html_safe来传递你传递的变量,如下所述。

但是,由于您想要影响外部文件,最好的技术是使用gon 。 另一个好的可能性是使用数据属性

gem专门为这项工作: https : //github.com/gazay/gon

可能是最强大的解决方案。

的Gemfile:

 gem 'gon' 

控制器:

 gon.timeleft = 1 

布局app/views/layouts/application.html.erb

    <%= include_gon %> <%= javascript_include_tag 'application' %> 

资产档案:

 gon.timeleft === 1 

数据属性

向属性添加值,使用JavaScript DOM操作检索它们。

有时被称为“不显眼的Javascript”。

查看头部:

 <%= javascript_include_tag 'application' %> 

查看正文:

 <%= content_tag 'div', '', id: 'data', data: {timeleft: '1'} %> 

资产档案:

 $(function() { parseInt($('#data').data('key1')) === 1 }) 

下面说明了escape_javascriptto_json如何在retro的答案之上使用。

escape_javascript

别名: j

仅适用于字符串。

将JavaScript字符串中具有特殊含义的字符(如反斜杠转义)转换为适合放入JavaScript字符串文字引号的格式。

保持输入的html_safe状态,因此需要html_safe否则特殊的HTML字符,如<将被转义为<

 <% a = "\\n<" %> <%= javascript_tag do %> f('<%= j(a) %>') // === '\\n<' f('<%= j(a).html_safe %>') // === '\\n<' <% end %> 

to_json + html_safe

可以工作,因为JSON 几乎是Javascript对象文字表示法的一个子集 。

不仅适用于散列对象,还适用于转换为相应数据类型的JSON片段的字符串,数组和整数。

 <% data = { key1: 'val1', key2: 'val2' } %> <%= javascript_tag do %> var data = <%= data.to_json.html_safe %> f(data.key1) \\ === 'val1' f(data.key2) \\ === 'val2' <% end %>