使用awesome_nested_set动态添加额外的子项

时间:2011-06-23 04:26:14

标签: ajax ruby-on-rails-3 nested-forms nested-sets

我有一个名为类别的嵌套模型,我创建了一个嵌套表单,允许在一个表单中创建一个类别和子类别。

如果您在新方法中预先构建子项,则可以正常工作:

class CategoriesController < InheritedResources::Base
  def new
    @category = Category.new
    @category.children.build
  end
end

当您想要使用AJAX在表单中动态添加新子项时,问题就开始发生了。

这是我的表格:

%table
    = form_for @category do |f|
        %tr
            %td= f.label :name
            %td= f.text_field :name

        %tr
            %td(colspan=2)
                %b Sub categories

        - @category.children.each do |sub|
            = f.fields_for :children, sub do |child|
                = render "child_fields", :f => child
        %tr
            %td= link_to_add_fields "Add sub category", f, :children
        %tr
            %td= f.submit 'Save'

这是我对link_to_add_fields的帮助方法(根据Ryans Railscast):

module ApplicationHelper
  def link_to_add_fields(name, f, association)
    new_object = f.object.class.reflect_on_association(association).klass.new

    fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
      render(:partial => association.to_s.singularize + "_fields", :locals => { :f => builder})
    end
    link_to_function(name, "add_fields(this, '#{association}', '#{escape_javascript(fields)}')")
  end  
end

这是Javascript的结尾

function add_fields(link, association, content) {
    // Generate new unique index, so base this off the current time.
    var new_id = new Date().getTime();
    var regexp = new RegExp("new_" + association, "g")

    // Replace new_association with the current time.    
    $(link).closest("tr").before(content.replace(regexp, new_id));
}

我注意到在预构建的子节点上,渲染的输出是这样的:

<input type="text" size="30" name="category[children_attributes][0][name]" id="category_children_attributes_0_name">

AJAX生成的字段在哪里:

<input type="text" size="30" name="category[children_attributes][1308801890744][name]" id="category_children_attributes_1308801890744_name">

这看起来是正确的但是当我去点击创建时,只保存了预建的孩子。

UPDATE1 如果我在我的def创建一个调试器行并键入params,我只看到我预先构建的类别而不是我动态添加的额外类别。

(rdb:4) params
{"utf8"=>"✓", "authenticity_token"=>"iwq1Vx3jOZZsjd79Nj+qKNXxOwWP40c8XDFS8ooGMdg=", "category"=>{"name"=>"1", "children_attributes"=>{"0"=>{"name"=>"2"}}}, "commit"=>"Save", "action"=>"create", "controller"=>"categories"}

1 个答案:

答案 0 :(得分:1)

这是因为当表单在表格内时,浏览器(至少是Firefox)表现得很奇怪。最简单/最快捷的解决方法是将表格放在表单中。这是对views / categories / new.haml文件的单行更改:

= form_for @category do |f|
    %table
        %tr

我如何调试它,以防它有帮助: 我首先检查了request.raw_post;参数不存在,这意味着rails甚至从未看到正确的请求。这指向了浏览器渲染问题。

我能够通过firebug调试问题,注意表单在渲染原始haml时笨拙地关闭了。将表单移出表格似乎可以在firefox中修复它。

我建议坚持div,主要是因为它避免了很多奇怪的浏览器问题。