简体   繁体   English

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

[英]Ruby on Rails - Send JavaScript variable from controller to external Javascript asset file

I am creating a website in Ruby on Rails. 我正在Ruby on Rails中创建一个网站。 I have a controller action that renders a view like so: 我有一个控制器动作,呈现如下视图:

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

This is fine as it renders the show.html.erb as I like. 这很好,因为它像我喜欢的那样呈现show.html.erb。 I would like however to somehow pass time_left to the view as a Javascript variable as this value is use by a countdown JQuery plugin. 然而,我想以某种方式将time_left作为Javascript变量传递给视图,因为这个值被倒计时JQuery插件使用。

I could put a javascript block on the page in the HTML and print a instance variable out like so: 我可以在HTML页面上放置一个javascript块并打印出一个实例变量,如下所示:

<script type="javascript"> $('#countdown').countdown('<%= @time_left =>')</script>

But I would like to keep all my JS in a external file and off the page could anyone give some advice on how to implement this? 但我想将所有的JS保存在一个外部文件中,在页面外可以有人就如何实现这一点给出一些建议吗?

Yes, you can! 是的你可以!

Rewrite your JS code into function with one argument (timelimit) and put it into some external file. 用一个参数(timelimit)将JS代码重写为函数,并将其放入一些外部文件中。 Then you can call the function from view and pass that @timeleft variable as JS function argument. 然后,您可以从视图中调用该函数,并将该@timeleft变量作为JS函数参数传递。

Short example: 简短的例子:

#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 javascript_tag

Example not tested, it is only idea not complete solution. 未经测试的示例,只是想法不完整的解决方案。 Don't forget to load that JS file. 不要忘记加载该JS文件。 You can use other JS rails helper javascript_include_tag . 您可以使用其他JS rails helper javascript_include_tag

retro's technique of using a function parameter is a possibility, but you have to properly escape the variable you are passing with either escape_javascript or to_json + html_safe as explained below. retro的使用函数参数的技术是可能的,但你必须正确地使用escape_javascriptto_json + html_safe来传递你传递的变量,如下所述。

However, since you want to affect external files, the best techniques will be to use gon . 但是,由于您想要影响外部文件,最好的技术是使用gon Another good possibility is to use data- attributes . 另一个好的可能性是使用数据属性

gon

Gem specialized for the job: https://github.com/gazay/gon 宝石专门为这项工作: https//github.com/gazay/gon

Probably the most robust solution. 可能是最强大的解决方案。

Gemfile: 的Gemfile:

gem 'gon'

Controller: 控制器:

gon.timeleft = 1

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

<html>
<head>
  <meta charset="utf-8"/>
  <%= include_gon %>
  <%= javascript_include_tag 'application' %>

Asset file: 资产档案:

gon.timeleft === 1

data- attributes 数据属性

Add values to attributes, retrieve them with JavaScript DOM operations. 向属性添加值,使用JavaScript DOM操作检索它们。

Sometimes called "unobtrusive Javascript". 有时被称为“不显眼的Javascript”。

View head: 查看头部:

<%= javascript_include_tag 'application' %>

View body: 查看正文:

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

Asset file: 资产档案:

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

The following illustrate how escape_javascript and to_json work for you to use on top of retro's answer. 下面说明了escape_javascriptto_json如何在retro的答案之上使用。

escape_javascript escape_javascript

Alias: j . 别名: j

Works only on strings. 仅适用于字符串。

Escapes characters that can have special meanings in JavaScript strings, like backslash escapes, into a format suitable to put inside JavaScript string literal quotes. 将JavaScript字符串中具有特殊含义的字符(如反斜杠转义)转换为适合放入JavaScript字符串文字引号的格式。

Maintains html_safe status of input, so needs html_safe otherwise special HTML chars like < would get escaped into &lt; 保持输入的html_safe状态,因此需要html_safe否则特殊的HTML字符,如<将被转义为&lt; .

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

to_json + html_safe to_json + html_safe

Works because JSON is almost a subset of Javascript object literal notation . 可以工作,因为JSON 几乎是Javascript对象文字表示法的一个子集

Works not only on hash objects, but also on strings, arrays and integers which are converted to JSON fragments of the corresponding data type. 不仅适用于散列对象,还适用于转换为相应数据类型的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 %>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM