19

这可能是我问过的比较困难的问题之一,但我被困了几天,我认为最好从更有经验的 Rails 社区获得支持。

我正在开发一个大致遵循本指南的虚拟应用程序...... ajax/jquery 教程......

进行我自己的自定义,该指南帮助我创建了一个“品牌”(包括嵌套模型“模型”、“子模型”和“样式”)提交表单(使用 simple_form)和品牌列表在同一页面上。这非常有效,并且强制执行验证(对于我的模型)。但是,当我将表单和品牌列表放在同一页面上时,我丢失了提交失败时出现的整洁的内联验证错误(见下图)。无法让内联错误正常工作让我意识到我需要了解更多关于渲染的知识。这就是为什么我专注于寻找这个问题的答案

在此处输入图像描述

...这是清单:

在此处输入图像描述

下面是索引操作的控制器:

  def index

    #This is for the product listing

    @brands = Brand.all.reverse 

    #This is for the form   

    @brand = Brand.new
    @model = Model.new
    @submodel = Submodel.new
    @style = Style.new

    respond_to do |format|
      format.html
    end
  end

上面的表单创建了用于嵌套提交表单的品牌、型号、子型号和样式......下面是表单的代码:

<%= simple_form_for @brand, :html => { :class => 'form-horizontal' }, :remote => true do |m| %>

  <fieldset style = "margin-top:34px;">
    <legend></legend>
    <%= m.input :name, :label => 'Brand' %>         
    <%= m.simple_fields_for :models, @model do |p| %>    
      <%= p.input :name, :label => 'Model' %>
      <%= p.simple_fields_for :submodels, @submodel do |s| %>
        <%= s.input :name, :label => 'Submodel' %>
        <%= s.simple_fields_for :styles, @style do |ss| %>
          <%= ss.input :name, :label => 'Style' %>
        <% end %>
      <% end %>
    <% end %>

    <div class="form-actions">
      <%= m.submit nil, :class => 'btn btn-primary' %>
      <%= link_to 'Cancel', brands_path, :class => 'btn' %>
    </div>
  </fieldset>
<% end %>

现在你可以看到我正在使用:remote => true......我希望表单创建新的“品牌”,或者让表单重新加载内联验证错误。目前我的创建动作看起来像:

def create
    @brand = Brand.new(params[:brand])

    respond_to do |format|
      if @brand.save
        format.html { redirect_to brands_url, notice: 'Brand was successfully created.' }
        format.json { render json: @brand, status: :created, location: @brand }
        format.js
      else
        format.html { render action: "index" }
        format.json { render json: @brand.errors, status: :unprocessable_entity }
        format.js { render 'reload' }
      end
    end
  end

出现在下面的代码if @brand.save似乎可以工作..但是“else”下面的代码不能按照我想要的方式工作。那么当@brand 不保存时会发生什么?我相信 index 操作中的代码正在运行,然后 @brand.errors 被转换为 json (我假设这是为了 simple_form 验证错误),然后 reload.js.erb 正在运行..

在尝试重新加载表单(出现验证错误)时,我已将该行$("#entryform").load(location.href+" #entryform>*","");放入 reload.js.erb ...当我将无效数据放入我的表单时,正在调用 reload.js.erb,但发生的只是表单字段重新加载空白,而不是输入数据和内联验证错误。

我希望我在这里提供了足够的信息来获得帮助。在这方面真的很挣扎。谢谢!

4

3 回答 3

30

我认为你可以通过将你的表单放在一个部分中(我们称之为它simple_form)来简化这一点,并将这段代码放在 reload.js.erb 中:

$("#entryform").html("<%= escape_javascript(render :partial => 'simple_form') %>");

我不熟悉 jQuery 的load方法,但我认为它会执行第二个请求。渲染错误的关键是您在渲染表单时使用的实例变量 ( @brand) 必须与您尝试在 create 中保存的变量相同,因此您可以检查其上的错误。这就是为什么您总是使用render而不是redirect_to在您想要呈现错误时使用。如果你做一个重定向,你会开始一个新的请求,意思@brand是重新初始化。我假设你$(...).load(...)有同样的问题。

于 2012-04-07T12:41:43.643 回答
1

感谢所有关于这个的问答。它救了我。

将@tsherif 的文件结构简化一个档次(假设您已经有一个 js 文件),我通过直接在表单上调用 render 并通过 javascript/coffeescript 显示它来解决这个问题。

#immediate_controller
def action_with_modal
  @brand = params[:failed_brand] || Brand.new
end

#brands_controller
def create
  @brand = Brand.new(params[:brand]) 

  respond_to do |format|
    if @brand.save
      ...
    else
      params[:failed_brand] = @brand
      ...
      format.js { render 'simple_form' }
    end
  end
end

#coffeescript
$('form-selectors-here').on 'ajax:error', @reRegister

reRegister: (e, data) =>
  $("div-that-contains-form").html(data.responseText)
于 2014-10-02T20:16:25.800 回答
0

检查这一点:调用 .html(...) 将复制表单包装器 div。使用 .replateWith(...) 代替 =]

于 2014-04-24T22:15:31.607 回答