无法弄清楚如何在Rails中使用remote: true来获取响应JSON

问题描述 投票:0回答:1

更新: 我发现问题是库依赖问题。我没有安装

jquery-rails
gem,因此我不需要在我的应用程序中使用
jquery-ujs
库。简而言之,当我只有可用的内置
jquery-ujs
功能时,我正在使用
rails-ujs
语法:((掌心)。感谢所有查看并提供和回答的人。


我觉得我正在做一些相当基本的事情,但由于某种原因我无法弄清楚我做错了什么。我可以使用

remote: true
帮助器的
form_for
选项,通过 AJAX 成功异步创建记录。但是,我尝试返回的简单 JSON 结构似乎在 AJAX 响应的
data
对象中不可用。当我运行
console.log(data)
时,我在浏览器 js 控制台中得到
undefined

这是我的代码的相当准确的表示:

视图中的表格:

= form_for :thing, remote: true, html: { id: 'thing' } do |f|
      = f.text_field :name
      = f.submit 'submit'

我的控制器代码:

def create
    @thing = Thing.new(thing_params)

    if @thing.save
      render json: { message: 'Thank you' }
    else
      render json: { message: 'oh no' } 
    end
end

我的 javascript/jQuery:

$(document).ready(function(){
      $('#thing').on('ajax:success', function(e, data, status, xhr) {
        console.log(data)
      }).on('ajax:error', function(e, xhr, status, error){
        console.log(error)
      });
})

我疯狂地用谷歌搜索,但我只是不知所措。但也许我忽略了一些非常简单的事情。我很感激任何建议。

ruby-on-rails ajax ruby-on-rails-6
1个回答
6
投票

Rails UJS 默认发送远程请求

application/javascript
内容类型。

如果您想请求 JSON,请将

data-type="json"
属性附加到元素:

= form_for @thing, remote: true, html: { id: 'thing' }, data: { type: "json" } do |f|
  = f.text_field :name
  = f.submit 'submit'

还有 Turbolinks 的问题。您的代码将事件处理程序直接附加到元素:

$('#thing').on('ajax:success', function(e, data, status, xhr) {
  console.log(data)
};

虽然这在初始页面加载时有效,但当 Turbolinks 用 Ajax 替换页面内容时,它就不起作用。相反,您需要创建一个幂等事件处理程序

$(document).on('ajax:success', '#thing', function(e, data, status, xhr) {
  console.log(data);
}).on('ajax:error', '#thing', function(e, xhr, status, error){
  console.log(error);
});

这会将一个事件处理程序附加到文档本身,该处理程序将在 DOM 冒泡时捕获该事件。 因此,您不需要将此代码包装在

$(document).ready(function(){ ... });
中。

您还应该返回有意义的 HTTP 响应代码 - 这将决定 Rails UJS 是否触发

ajax:success
ajax:error
。不是 JSON 消息,它是反模式。

def create
  @thing = Thing.new(thing_params)

  if @thing.save
    # Tell the client where the newly created object can be found
    head :created, location: @thing
    # or return a json representation of the object
    render json: @thing, status: :created
  else
    # just return a header 
    head :unprocessable_entity
    # or return a JSON object with the errors
    render json: { errors: @thing.errors }, status: :unprocessable_entity
  end
end
© www.soinside.com 2019 - 2024. All rights reserved.