简体   繁体   English

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

[英]How to pass Ruby variables to a JavaScript function in a Rails view?

I'm wondering what the best practice is for passing variables to JavaScript functions in a rails view.我想知道在 Rails 视图中将变量传递给 JavaScript 函数的最佳实践是什么。 Right now I'm doing something like:现在我正在做类似的事情:

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

Is this the right way to go about it?这是正确的方法吗?

A few options:几个选项:

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 %>
  '<%= j(a)           %>' === '\\n&lt;'
  '<%= j(a).html_safe %>' === '\\n<'
<% end %>

to_json + html_safe to_json + html_safe

As mentioned by Vyacheslav, go upvote him.正如维亚切斯拉夫所说,去给他投票。

Works because JSON is almost a subset of Javascript object literal notation .之所以有效,是因为 JSON几乎是 Javascript object literal notation 的一个子集

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 %>
  data.key1 === 'val1'
  data.key2 === 'val2'
<% end %>

data- attributes数据属性

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

Better with the content_tag helper:使用content_tag助手更好:

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

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

gon

Library specialized for the job: https://github.com/gazay/gon专门用于这项工作的图书馆: https : //github.com/gazay/gon

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

Gemfile:宝石档案:

gem 'gon'

Controller:控制器:

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

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

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

View:看法:

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

See also也可以看看

- 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

There's a technique called "unobtrusive javascript".有一种技术叫做“unobtrusive javascript”。 Here's a Railscast about it: link text .这是关于它的 Railscast:链接文本 It works both with prototype an jQuery.它适用于原型和 jQuery。 There are also plugins that can help simplify some of the tasks described in the article.还有一些插件可以帮助简化文章中描述的一些任务。

我发现 gem客户端变量,它可以帮助您轻松完成。

In HAML can data are presented so:在 HAML 中,数据可以这样呈现:

.position{data: {latitude: @claim.latitude.to_json, longitude: @claim.longitude.to_json}}

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

Note that if you aren't using escape_javascript in a view, you can include it in your ruby code like so:请注意,如果您没有在视图中使用escape_javascript ,您可以将它包含在您的 ruby​​ 代码中,如下所示:

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

or if that wont work for you, then copy the source of the function in to your code, if need be:或者如果这对您不起作用,则将函数复制到您的代码中,如果需要的话:

  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

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

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