Rails:将数据传递到JavaScript

24

我是Rails的新手,在一个控制器中我有以下代码:

class PagesController < ApplicationController
   def home
      @temp = "Hello"
   end
end

我已经阅读到必须将JavaScript代码放在application.js文件中(如果正确请告诉我),我已经:

window.onload=function(){alert("<%= j @temp %>")}

显然那个警告打印了字符串"<%= j @temp %>" 我该如何将变量@temp传递给JavaScript,以便警告框可以打印出Hello?

谢谢


这两个解决方案有一个起作用了吗? - Powers
可能是重复的问题,参考Ruby on Rails - Send JavaScript variable from controller to external Javascript asset file,或者如果您不需要外部Js文件,请参考https://dev59.com/-HE95IYBdhLWcg3wE52C。 - Ciro Santilli OurBigBook.com
3个回答

65

我写了一篇关于如何将Ruby对象传递给客户端的文章。Ryan Bates也有一个优秀的RailsCast,介绍如何将数据传递给JS

在你的视图中添加一个div,它对应于PagesControlle#home操作,在加载页面时不可见,但包含存储在Ruby对象中的数据:

# views/pages_controllers/home.html.erb
<%= content_tag :div, class: "temp_information", data: {temp: @temp} do %>
<% end %>

在包含此 .temp_information div 的页面上加载并查看页面源代码。您可以看到您的 Ruby 对象存储在其中。打开 JavaScript 控制台以作为 JavaScript 对象访问 Ruby 对象。
$('.temp_information').data('temp')

您无需将JS添加到JS局部文件中,也可以使用资产管道。


1
你的答案对我有用。谢谢! - Niyanta

5

我做的事情类似于 gon,但更加简单。我在我的ApplicationController中实现了以下内容。

def javascript_variables(variables)
  @javascript_variables ||= {}
  @javascript_variables.merge!(variables)
end

在控制器操作中,我可以像这样执行某些操作:
def some_action
  javascript_variables(user: current_user)
end

在我的ApplicationHelper中,我有类似以下的代码。
def javascript_variables(variables = nil)
  @javascript_variables ||= {}
  @javascript_variables.merge!(variables) and return if !variables.nil?

  output  = ''
  padding = @javascript_variables.keys.group_by(&:size).max.first

  @javascript_variables.each do |variable, value|
    output << "#{variable.to_s.ljust(padding)} = #{value.to_json},\n          "
  end

  raw "var " + output.strip.html_safe.gsub(/\,\Z/m, ';')
end

最后,在我的布局的 <head> 中,我有以下内容。
<script>
  <%= javascript_variables %>
</script>

这使我得到了像这样的东西(来自我的应用程序中的真实例子)
<script>
  var pageModule        = "site/index",
      isCustomer        = false,
      utype             = "normal",
      isAnonymous       = true,
      keyboardShortcuts = false,
      pubnub            = null,
      requestToken      = "3zj974w074ftria3j";
</script>

这个方法会不会让网站更容易受到攻击? - dotcomXY
1
我不确定这是一个问题还是陈述,所以我不知道该如何回答。 - deefour
3
不应创建太多的全局变量,而是创建一个单独的对象,并将值存储为其属性。 - Juliusz Gonera
你的方法很棒,但如果没有从控制器传递的 JavaScript 变量,则你助手(helper)的代码会导致错误。正确的代码是 `@javascript_variables ||= {} \n@javascript_variables.merge!(variables) if !variables.nil? \n return if @javascript_variables == {}` 我在注释中使用了 `\n` 来分隔代码行。 - zavg

0

看一下这个。

http://tech.thereq.com/post/17243732577/rails-3-using-link-to-remote-true-with-jquery-ujs

其中最简单的方法是使用js.erb文件,在这里你可以使用ruby标签来访问在控制器动作中定义的变量。

你需要在控制器动作中使用respond_to块,指定响应javascript的动作。

items_controller.rb

class ItemsController < ApplicationController

  def action
    respond_to do |format|
      format.js
      #format.html {}    #  These are for allowing other types of formats to be responded to.
      #format.json {}    #  But they are not necessary for using this js.erb way of doing things.
    end
  end

end

/views/items/action.js.erb

$(div).html('The cat has erased your page');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接