【问题标题】:Rails - why isn't ajax sending params to GET requestRails - 为什么 ajax 不向 GET 请求发送参数
【发布时间】:2016-06-02 23:23:26
【问题描述】:

我正在尝试使用 ajax 通过获取请求发送数据,但似乎没有发送参数。我有一个页面显示来自数据库的随机项目。您可以通过导航栏中的链接访问此页面。进入此页面后,有一个链接可让您跳过当前项目以查找另一个随机项目,以确保下一个项目不是用户刚刚查看的项目。

routes.rb

get 'pending', to: 'items#pending'

查看

<%= link_to 'Skip', '', class: "btn btn-default btn-xs",
                     id: "skip-btn",
                     :'data-item-id' => @pending_item.id %>

控制器

def pending
    @previous_pending_item_id = params[:id] || 0
    @pending_items = Item.pending.where("items.id != ?", @previous_pending_item_id)
    @pending_item = @pending_items.offset(rand @pending_items.count).first
    respond_to do |format|
      format.js
      format.html
    end
  end

我对 html 和 js 都有响应,因为我正在使用导航栏链接的操作以及页面上的链接。页面上的链接是跳过按钮,应该会弹出另一个随机项目。

sitewide.js.erb

  $('#skip-btn').on('click', function () {
    $.ajax({
      data: {id: $(this).data("item-id")},
      url: "/pending"
    });
  });

当我查看服务器日志时显示Started GET "/pending"...,但没有提及正在发送的参数。我错过了什么?

我为此使用 ajax 的原因是我不希望参数显示在 url 中。

为澄清起见,我需要在访问此页面时始终将 url 设为 /pending,并且在 url 中标识没有参数或附加 :id。此页面应始终显示来自 db 的随机记录。我需要发送参数的唯一原因是确保没有记录是连续重复的,即使它们是随机的。

【问题讨论】:

  • 网络请求中的id看到了吗?
  • @epascarello 我在哪里可以找到这个?我正在使用 chrome 浏览器
  • 添加一个 console.log($(this).data("item-id")) 以确保有东西要发送
  • 在待处理操作的开头添加“p 参数”以在终端中查看正在传递的内容
  • 在 Chrome 的开发者控制台中查看网络面板

标签: javascript ruby-on-rails ajax


【解决方案1】:

我认为您需要阻止默认链接操作:

  $('#skip-btn').on('click', function (event) {
    event.preventDefault();
    ...
  });

【讨论】:

  • 这有帮助。现在终端显示参数,但现在页面没有带我去任何地方。该按钮看起来像是被点击了,但没有任何反应。
  • 所以我使用 ajax 的原因是将信息发送到控制器而不显示在 url 中。你知道有没有更好的方法来做到这一点?如果没有,我将如何强制刷新页面?
  • 您可以重新渲染页面作为响应
  • 我该怎么做。我试过format.js {render :action =&gt; "pending"},但似乎什么也没做。
【解决方案2】:

虽然您可以按照您尝试的方式进行操作,但我认为值得指出的是,在 GET 请求中发送数据有点反模式。那么为什么不以“正确”的方式来做呢!

将您的 routes.rb 更改为:

get 'pending/:id', to: 'items#pending'

并将 sitewide.js.erb 更改为:

$('#skip-btn').on('click', function () {
    $.ajax({
      url: "/pending/" + $(this).data("item-id")
    });
  });

【讨论】:

  • 您的回答出现 404 not found 错误,所以我也尝试了 `url: "/pending?=" + $(this).data("item-id") 但现在当我单击按钮没有任何反应。在终端中查看它看起来确实有一个获取请求正在发送到 /pending?=33
  • id 字段不需要 ?=,但它确实需要在 pending 和 id 编号之间使用 /。你添加了吗?
  • 是的,但我的路线设置为不接受 :id。访问/挂起时,用户记录应该是随机的,我不希望用户能够返回到特定记录。我希望此页面上的 url 始终显示为 /pending 但我需要一种发送参数的方法,以便永远不会连续重复相同的记录
  • 那么我会编辑我的答案,这与您提出的问题有点不同。
  • 我很抱歉造成混乱。我可以尝试编辑我的问题以澄清。
【解决方案3】:

我希望您检查将查询发送到您的控制器的格式。以及您希望在前端接收的格式类型。

$('#skip-btn').on('click', function (e) {
  e.preventDefault();
  $.ajax({
    dataType: 'json', //This will ensure we are receiving a specific formatted response
    data: {id: $(this).data("item-id")},
    url: "/pending"
  });
});

在您的控制器中,您可能希望将其作为 json 对象传回。

def pending
  #@previous_pending_item_id = params[:id] || 0
  #No need to make it an instance variable
  previous_pending_item_id = params[:id] || 0

  #Same goes for pending_items. No need to make it a instance variable, unless you're using it somewhere else.
  pending_items = Item.pending.where("items.id != ?", previous_pending_item_id)
  @pending_item = pending_items.offset(rand pending_items.count).first
  respond_to do |format|
    format.js
    format.html
    format.json { render json: @pending_item.as_json }
  end
end

这样您就可以从响应中获取价值并将其附加到您的页面。

同样,如果您期待 jshtml 回复,您应该在您的 ajax 调用中提及这一点。如果它确实可以帮助您解决问题,请告诉我。

更新:

假设在你的页面中,它将@pending_item对象的数据显示在一个div中,

&lt;div id="pending_item"&gt;...&lt;/div&gt;

当您向控制器发出 ajax 请求时,您希望 div#pending_item 显示一个新的随机pending_item。

$('#skip-btn').on('click', function (e) {
  e.preventDefault();
  $.ajax({
    dataType: 'html', //we'll receive a html partial from server
    data: {id: $(this).data("item-id")},
    url: "/pending",
    success: function(res){
      //We'll set the html of our div to the response html we got
      $("#pending_item").html(res);
    }
  });
});

在您的控制器中,您可以执行以下操作:

format.html { render partial: 'pending_item', layout: false }

在您的部分文件“_pendint_item.html.erb”中,您将访问您的实例变量@pending_item 并显示数据

这会将响应以 html 的形式发送到服务器,您只需将 div 的 html 设置为此。

更新 2

您的部分可能看起来像这样,或者只是您想要显示待处理项目。要知道的是,它将访问您在控制器方法中定义的同一实例变量 @pending_item,除非您将 locals 传递给它。

<div class="pending_item">
  <h3><%= @pending_item.name %></h3>
  <p><%= @pending_item.description %></p>
</div>

我建议您在 ajax 调用的成功回调中执行 console.log(res) 以查看您从服务器返回的内容。

【讨论】:

  • 我对这里为什么使用 json 感到困惑。我只需要将 id 参数发送到控制器的待处理操作并呈现 pending.html.erb
  • 好的。因此,当您通过 ajax 向控制器发送数据时,它不会重新加载您的页面,也不会自动将任何内容加载到页面中。这就是使用 ajax 异步执行所有操作的全部意义所在。因此,如果您想通过 ajax 调用呈现页面,则必须自己完成。在我们的例子中,当我们收到 @pending_item 对象的 json 响应时,我们将把它从其数据中创建一个 html 元素并将其附加到我们的 DOM 中。
  • 你说对于部分我将访问实例变量并显示数据。这是什么意思,局部应该是什么样子?如果我想要重新渲染整个页面的效果,这是否意味着我必须将部分(_pending_item.html.erb)设置为与pending.html.erb完全相同?
猜你喜欢
  • 1970-01-01
  • 2016-04-18
  • 2017-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-25
  • 2014-03-26
  • 1970-01-01
相关资源
最近更新 更多