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

Rai*_*Son 11 javascript ruby-on-rails

我正在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
Run Code Online (Sandbox Code Playgroud)

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

我可以在HTML页面上放置一个javascript块并打印出一个实例变量,如下所示:

<script type="javascript"> $('#countdown').countdown('<%= @time_left =>')</script>
Run Code Online (Sandbox Code Playgroud)

但我想将所有的JS保存在一个外部文件中,在页面外可以有人就如何实现这一点给出一些建议吗?

ret*_*tro 7

是的你可以!

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

简短的例子:

#controller
@time_left = Time.now.to_i - 3.hours.to_i
Run Code Online (Sandbox Code Playgroud)

.

#javascript
function count_down(time_left) {
  $('#countdown').countdown(time_left)
}
Run Code Online (Sandbox Code Playgroud)

.

#view
<%=javascript_tag "count_down(#{@time_left})" -%>
Run Code Online (Sandbox Code Playgroud)

javascript_tag

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


Cir*_*四事件 5

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

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

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

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

的Gemfile:

gem 'gon'
Run Code Online (Sandbox Code Playgroud)

控制器:

gon.timeleft = 1
Run Code Online (Sandbox Code Playgroud)

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

<html>
<head>
  <meta charset="utf-8"/>
  <%= include_gon %>
  <%= javascript_include_tag 'application' %>
Run Code Online (Sandbox Code Playgroud)

资产档案:

gon.timeleft === 1
Run Code Online (Sandbox Code Playgroud)

数据属性

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

有时被称为"不显眼的Javascript".

查看头部:

<%= javascript_include_tag 'application' %>
Run Code Online (Sandbox Code Playgroud)

查看正文:

<%= content_tag 'div', '', id: 'data', data: {timeleft: '1'} %>
Run Code Online (Sandbox Code Playgroud)

资产档案:

$(function() {
  parseInt($('#data').data('key1')) === 1
})
Run Code Online (Sandbox Code Playgroud)

以下说明了如何使用复古的答案escape_javascriptto_json使其工作.

escape_javascript

别名:j.

仅适用于字符串.

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

保持html_safe输入的状态,因此需要html_safe特殊的HTML字符,如<将被转义&lt;.

<% a = "\\n<" %>
<%= javascript_tag do %>
  f('<%= j(a)           %>') // === '\\n&lt;'
  f('<%= j(a).html_safe %>') // === '\\n<'
<% end %>
Run Code Online (Sandbox Code Playgroud)

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 %>
Run Code Online (Sandbox Code Playgroud)