如何在 Rails 视图中将 Ruby 变量传递给 JavaScript 函数?

Posted

技术标签:

【中文标题】如何在 Rails 视图中将 Ruby 变量传递给 JavaScript 函数?【英文标题】:How to pass Ruby variables to a JavaScript function in a Rails view? 【发布时间】:2021-07-23 02:47:19 【问题描述】:

我想知道在 Rails 视图中将变量传递给 javascript 函数的最佳做法是什么。现在我正在做类似的事情:

<% content_for :javascript do %> 
  <script type="text/javascript">
    Event.observe(window, 'load', function()          
        js_function(<%= @ruby_array.to_json %>, <%= @ruby_var %>); )
  </script>
<% end %>

这是正确的做法吗?

【问题讨论】:

【参考方案1】:

有一种技术叫做“unobtrusive javascript”。这是关于它的 Railscast:link text。它适用于原型 jQuery。还有一些插件可以帮助简化文章中描述的一些任务。

【讨论】:

【参考方案2】:
- content_for :javascripts_vars do
  = "var costs_data = #@records[:cost_mode][:data].to_json".html_safe
  = "var graph_data = #@records[:cost_mode][:graph].to_json".html_safe

【讨论】:

【参考方案3】:

我找到了 gem client variable,它可以帮助您轻松完成。

【讨论】:

请尝试阅读此***.com/help/deleted-answers,以进一步了解如何回答。即:“没有从根本上回答问题的答案”:仅是指向外部网站的链接【参考方案4】:

几个选项:

escape_javascript

别名:j

仅适用于字符串。

转义 Javascript 字符串中可能具有特殊含义的字符, 像反斜杠转义一样,转换成适合放在 Javascript 字符串文字引号内的格式。

保持html_safe输入状态, 所以需要html_safe,否则像&amp;lt;这样的特殊HTML字符会被转义到&amp;lt;

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

to_json + html_safe

正如维亚切斯拉夫所说,去投票给他。

有效,因为 JSON 是 almost a subset of Javascript object literal notation。

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

<% data =  key1: 'val1', key2: 'val2'  %>
<%= javascript_tag do %>
  var data = <%= data.to_json.html_safe %>
  data.key1 === 'val1'
  data.key2 === 'val2'
<% end %>

数据属性

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

使用content_tag 助手会更好:

<%= content_tag 'div', '', id: 'data', data: key1: 'val1', key2: 'val2' %>
<%= javascript_tag do %>
  $('#data').data('key1') === 'val1'
  $('#data').data('key2') === 'val2'
<% end %>

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

专门用于该工作的图书馆:https://github.com/gazay/gon

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

宝石文件:

gem 'gon'

控制器:

gon.key1 = 'val1'
gon.key2 = 'val2'

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

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

查看:

<%= javascript_tag do %>
  gon.key1 === 'val1'
  gon.key2 === 'val2'
<% end %>

另请参阅

Injecting variable values into javascript and HAML in RoR

【讨论】:

【参考方案5】:

在 HAML 中可以这样显示数据:

.positiondata: latitude: @claim.latitude.to_json, longitude: @claim.longitude.to_json

:javascript
   var latitude = $('.position').data('latitude');
   var longitude = $('.position').data('longitude');

【讨论】:

【参考方案6】:

请注意,如果您没有在视图中使用escape_javascript,您可以像这样使用include it in your ruby code:

require 'action_view/helpers/javascript_helper'
include ActionView::Helpers::JavaScriptHelper
# escape_javascript is available here.

或者如果这对您不起作用,则将 source of the function 复制到您的代码中(如果需要):

  JS_ESCAPE_MAP = 
    '\\'    => '\\\\',
    "</"    => '<\/',
    "\r\n"  => '\n',
    "\n"    => '\n',
    "\r"    => '\n',
    '"'     => '\\"',
    "'"     => "\\'"
  

  JS_ESCAPE_MAP["\342\200\250".dup.force_encoding(Encoding::UTF_8).encode!] = "&#x2028;"
  JS_ESCAPE_MAP["\342\200\251".dup.force_encoding(Encoding::UTF_8).encode!] = "&#x2029;"

  # Escapes carriage returns and single and double quotes for JavaScript segments.
  #
  # Also available through the alias j(). This is particularly helpful in JavaScript
  # responses, like:
  #
  #   $('some_element').replaceWith('<%= j render 'some/element_template' %>');
  def escape_javascript(javascript)
    if javascript
      result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"'])/u)  |match| JS_ESCAPE_MAP[match] 
      javascript.html_safe? ? result.html_safe : result
    else
      ""
    end
  end

【讨论】:

以上是关于如何在 Rails 视图中将 Ruby 变量传递给 JavaScript 函数?的主要内容,如果未能解决你的问题,请参考以下文章

在 ruby​​ on rails 中将参数从视图传递到控制器

如何将javascript变量传递给嵌入式ruby?

Rails - 将信息从视图传递到 Javascript

ruby on rails 在关联调用中使用变量

如何在 django 的基于类的视图中将值传递给模板?

Ruby on Rails 将盐传递给 Digest::SHA512