【问题标题】:How do I send a JavaScript value to Rails Controller using AJAX?如何使用 AJAX 将 JavaScript 值发送到 Rails 控制器?
【发布时间】:2020-03-18 18:15:20
【问题描述】:

在我的应用程序的dashboard 页面中,我想显示一个地图图例,该图例根据提供给显示此图例的 HTML 的值动态填充。

这就是图例的样子:

我正在使用 javascript 填充此图例;我的 JavaSCript 函数返回一个嵌套哈希数组,看起来像这样:

[
   {title: 'Downtown Loft', color:'#ade8ad'},
   {title: 'Midtown Mansion', color:'#bd95ff'}
]

问题

为了实现这一点,我需要能够将上面的数组从我的pages.js.erb 文件发送到我的pages_controller.rb 文件,特别是dashboard 操作。在这个控制器方法中,我会将 JavaScript 中的数据分配给一个名为 @calendar_legend 的实例变量

为了验证这是否有效,我将在我的dashboard.html.erb 视图中调用<%= @calendar_legend %> 并期望它显示数组...不幸的是这不起作用。

我已经在我的控制器中尝试了render json: @calendar_legend,并且在查看该页面时我总是得到null 值。

这是我尝试将数据发送到控制器的方式:

function calendarLegend(){
  const legendarray = [
    {title: 'Downtown Loft', color:'#ade8ad'}, 
    {title: 'Midtown Mansion', color:'#bd95ff'}
  ]

  $.ajax({
      type:'POST',
      url: 'pages/dashboard',
      data: JSON.stringify(legendarray),
      contentType: 'application/json'
  });
};

$(document).ready(function(){
  calendarLegend();
});

这是我尝试在我的控制器中分配它的方式

def dashboard
   @calendar_legend = params[:legendarray]
   render json: @calendar_legend
end 

在我看来

<%= @calendar_legend %>

这与我在 Stackoverflow 和其他各种网站上找到的任何其他解决方案一样无效。

【问题讨论】:

    标签: javascript ruby ajax controller


    【解决方案1】:

    问题是您正在渲染尚未设置的变量@calendar_legend。此外,Ajax 函数在调用后不会在页面上呈现结果。

    我不完全确定您要在这里完成什么,但这里有一些建议。

    首先,您可以在加载dashboard.html.erb 页面的控制器操作中设置@calendar_legend 变量(而不是在使用Ajax 加载页面后调用另一个操作)。如果这样做,您可以完全删除 Ajax 函数。

    其次,如果您设置在页面加载后尝试加载数据以更改图例,则需要处理来自服务器的响应。有两种方法可以轻松做到这一点:

    1. 在 AJAX 方法中添加响应处理程序(来自 jQuery Ajax 文档的示例 - https://api.jquery.com/jquery.ajax/) - 在此示例中,.done 函数中的“数据”变量将包含您正在呈现为的 @calendar_legend 的值json 来自控制器操作,因此您需要将其添加到页面中:

      $.ajax({
        type: 'POST',
        url: "pages/dashboard",
        data: JSON.stringify(legendarray),
        contentType: 'application/json'
      }).done(function(data) {
        $('.div-with-calendar-legend-data-inside').html( data );
      });
      
    2. 您也可以使用与控制器操作同名的 js.erb 模板对 Rails 执行此操作(而不是将响应处理程序添加到 Ajax 函数)。首先,您将修改控制器操作以仅设置变量而不渲染任何内容(而是让 Rails 渲染 js.erb 模板):

      def dashboard
        @calendar_legend = params[:legendarray]
      end
      

    然后创建模板 app/views/pages/dashboard.js.erb,并在其中添加如下内容:

    $('.div-with-calendar-legend-data-inside').html( <%= @calendar_legend %> );
    

    这两个选项都需要您在视图中添加一个 div(带有类或 ID)以将 @calendar_legend 数据添加到:

        <div class="div-with-calendar-legend-data-inside">
          <%= @calendar_legend %>
        </div>
    

    通常,如果您在用户在页面上进行更改时尝试重新加载图例(即,他们从下拉列表或其他表单输入中选择某些内容),我只会尝试使用 Ajax 加载数据 - 然后您可以使用 Ajax 将数据发送到控制器并让它更新图例而不刷新页面。但是,这样做时,我将只使用 form_tag 并在其上设置 remote: true ,然后在输入更改时使用 jquery 提交表单并使用 js.erb 模板处理响应 - 我认为这比使用 Ajax 更干净功能。

    希望这会有所帮助

    【讨论】:

    • 感谢您的回复... 明确地说,我不希望/偏好使用 AJAX 来完成此操作,我了解 AJAX 的主要目的是实时更新客户端而不刷新,这不是我的本意。我只尝试了 AJAX,因为它允许 JS 与 Rails 对话。虽然您的解决方案可能会起作用,但我认为它不适合我的用例。如果您能详细说明您的回复的这一部分,那就太好了:“首先,您可以在控制器操作中设置 @calendar_legend 变量......”
    • 我刚刚意识到我完全可以在 Ruby 中完成这项工作
    • 我只使用 ruby​​ 解决了这个问题。出于不重要的原因,我试图用完全不必要的 javascript 生成这个数组。我添加此评论是因为我觉得这不是一个好问题,但给出的答案非常有用!
    猜你喜欢
    • 2019-06-21
    • 2021-12-05
    • 2021-10-23
    • 2011-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-15
    • 1970-01-01
    相关资源
    最近更新 更多