簡體   English   中英

如何在 Rails 視圖中將 Ruby 變量傳遞給 JavaScript 函數?

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

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

這是正確的方法嗎?

幾個選項:

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幾乎是 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 %>

也可以看看

- 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

有一種技術叫做“unobtrusive javascript”。 這是關於它的 Railscast:鏈接文本 它適用於原型和 jQuery。 還有一些插件可以幫助簡化文章中描述的一些任務。

我發現 gem客戶端變量,它可以幫助您輕松完成。

在 HAML 中,數據可以這樣呈現:

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

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

請注意,如果您沒有在視圖中使用escape_javascript ,您可以將它包含在您的 ruby​​ 代碼中,如下所示:

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

或者如果這對您不起作用,則將函數復制到您的代碼中,如果需要的話:

  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