控制器无法检测到Ajax请求

我正在使用simple_form gem并生成我指定remote:true选项的表单,如下所示:

 

因此,表单的输出html是以下片段:

 
...

在我检查时,使用标准的form_for帮助程序是在使用remote:true选项时将data-remote =’true’添加到表单中。 从生成的html中可以看出,当我使用simple_form gem时,也有这样的属性。

所以,在我的控制器中我有:

 def create @webinar = Webinar.new(params[:webinar]) respond_to do |format| if @webinar.save format.html { redirect_to @webinar, notice: 'Webinar was successfully created.' } format.js format.json { render json: @webinar, status: :created, location: @webinar } else format.html { render action: "new" } format.json { render json: @webinar.errors, status: :unprocessable_entity } end end end 

但是,始终使用format.html 。 我做错了什么?

编辑:

我使用了logger.debug request.format来检查请求的实际格式是什么,在日志文件中它是:

text / html的

所以,问题必须是simple_form生成的forms – 当我们有“data-remote = true”时,那里会出现什么问题?

你将format.json|format.htmlremote: true混淆了。 两者都不同。 remote: true存在并不意味着format.json

format.json 不表示通过javascript调用了URL。 它只表示客户端需要JSON输出 。 即它不表示输入来自哪里,它表示需要什么输出。

remote:true的一般用法是,不是重新加载页面,而是将表单作为Ajax请求提交,然后在JQuery弹出窗口中显示响应。 但是如果你想将响应显示为JQuery弹出窗口 – 你需要HTML输出,而不是JSON输出吗?

有些人使用remote: true在弹出窗口中加载HTML内容。 你的用例是做remote: true但你期望JSON格式的数据。 Rails无法为您做出这些决定。 默认情况下,它会将请求发送到/webinars并期望您将处理HTML响应。 如果您真的想要JSON响应 – 那么自定义发布Ajax请求的URL:

 simple_form_for @webinar, url: webinar_path(format: :json), ..... 

如果您执行上述操作,现在将使用JSON格式调用网络研讨会控制器。

总体:

  • remote:true可以与format.jsonformat.json
  • Rails应用程序中的大多数用例是像往常一样处理remote: true作为控制器请求,渲染部分HTML模板(即单独的响应内容而没有整个页面布局/导航/等)并将其作为HTML发送回来显示在弹出窗口中
  • 大多数人只是一揽子处理远程回调并显示一个JQuery弹出窗口。 因此,他们不需要为每个远程表单编写单独的代码
  • 因此,默认情况下,Rails为远程请求调用format.html
  • 如果您特别需要format.json ,并且如果您真的想在客户端上手动处理JSON,请相应地更改URL。 但这不是大多数用例
  • 发出Ajax请求并不意味着内容类型是JSON。 这是使用Javascript进行的HTML请求。 例如,在jquery $.ajax方法中,检查以下两个选项: acceptdataType 。 如果你真的想发送Accepts: application/json header,那么你必须在发出Ajax请求时手动指定(或者你需要使用.json结束url如果它是一个Rails应用程序)。
  • 因此,即使您向/webinars format.json提出正常的Ajax请求,例如$.ajax('/webinars', ...) format.json $.ajax('/webinars', ...) – 它也不会转到format.json ! 它仍然只会转到format.html 。 如果你真的想要一个JSON格式,那么你必须说$.ajax('/webinars', { accepts: 'application/json' }) ,或者你必须说$.ajax('/webinars.json')

编辑:轻微澄清

您似乎没有直接在生成的表单操作中请求JSON格式的文档。 也许一个选项是使用这种技术在您的路径文件中设置:format to json : http : //guides.rubyonrails.org/routing.html#defining-defaults

您还可以通过为:defaults选项提供哈希来定义路由中的其他默认值。 这甚至适用于未指定为动态段的参数。 例如:

 match 'photos/:id' => 'photos#show', :defaults => { :format => 'jpg' } 

Rails会将Photos / 12与PhotosController的show动作匹配,并将params [:format]设置为“jpg”。

我无法相信我已经失去了太多时间来试图理解为什么simple_form没有按预期工作。

最后,似乎我已经以正确的方式完成了所有事情,问题是由于:

AJAX不能用于文件上传。

为了解决我的问题,我只需要将以下gem添加到我的Gemfile中并运行bundle install命令:

 gem 'remotipart', '~> 1.0' 

然后在我的application.js文件中添加以下行:

// =需要jquery.remotipart

更多信息:

  1. remotipartgem
  2. 如何使用jQuery上传多个文件