7

I am using simple_form gem and generating the form I am specifying the remote:true option like this:

<%= simple_form_for @webinar, validate: true, remote:true do |f| %>

So, the output html for the form is the following fragment:

<form accept-charset="UTF-8" action="/webinars" class="simple_form new_webinar" data-remote="true" data-validate="true" enctype="multipart/form-data" id="new_webinar" method="post" novalidate="novalidate"> ... </form>

As I checked, using the standard form_for helper is adding the data-remote='true' to the form when remote:true options is used. And as you can see from the generated html, when I am using the simple_form gem there is such attribute, too.

So, in my controller I have:

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

But, always the format.html is used. What i am doing wrong?

EDIT:

I have used logger.debug request.format to check what is the actual format ask for and in the log file it was:

text/html

So, the issue must be in the simple_form generated form - what can be wrong there when we have "data-remote=true"?

4

3 回答 3

4

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

format.json 并不表示URL 是通过 javascript 调用的。这仅意味着客户端期望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.htmlformat.json
  • Rails 应用程序中的大多数用例是remote: true像往常一样作为控制器请求处理,呈现部分 HTML 模板(即仅响应内容而没有整体页面布局/导航/等)并将其作为 HTML 发送回以显示在弹出
  • 大多数人只是笼统地处理远程回调并显示一个 JQuery 弹出窗口。所以他们不需要为每个远程表单编写单独的代码
  • 所以默认情况下,Rails 调用format.html远程请求
  • 如果您特别想要format.json,并且如果您真的想在客户端手动处理 JSON,请相应地更改 URL。但这不是大多数用例
  • 发出 Ajax 请求并不意味着内容类型是 JSON。它是使用 Javascript 发出的 HTML 请求。例如在jquery$.ajax方法中,检查这两个选项:acceptdataType. 如果您真的想发送Accepts: application/json标头,那么您必须在发出 Ajax 请求时手动指定(或者.json如果它是 Rails 应用程序,则需要以 url 结束)。
  • 因此,即使您发出一个正常的 Ajax 请求/webinars,比如$.ajax('/webinars', ...)- 它也不会去format.json!它仍然只会去format.html。如果你真的想要一个 JSON 格式,那么你必须说$.ajax('/webinars', { accepts: 'application/json' }),或者你必须说$.ajax('/webinars.json')

编辑:小澄清

于 2013-06-08T08:19:20.320 回答
2

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

最后,看来我已经以正确的方式完成了所有事情,而导致问题的原因是:

AJAX 不能用于文件上传。

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

gem 'remotipart', '~> 1.0'

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

//= 需要 jquery.remotipart

更多信息:

  1. 远程宝石
  2. 如何使用 jQuery 上传多个文件
于 2013-06-08T18:31:10.293 回答
2

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

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

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

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

于 2013-06-07T21:45:19.403 回答