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

问题描述 投票:11回答:6

我想知道在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 %>

这是正确的方法吗?

javascript ruby-on-rails prototypejs
6个回答
21
投票

一些选择:

escape_javascript

别名:j

仅适用于字符串。

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

保持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

正如维亚切斯拉夫所提到的那样,请向他投票。

因为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

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

的Gemfile:

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 %>

也可以看看


6
投票
- 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

2
投票

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


0
投票

我发现宝石client variable,它可以帮助你轻松地做到这一点。


0
投票

在HAML中可以显示数据:

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

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

0
投票

请注意,如果您未在视图中使用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
© www.soinside.com 2019 - 2024. All rights reserved.