当前位置: 首页 > 面试题库 >

AJAX更新accepts_nested_attributes_for局部文件

傅宏恺
2023-03-14
问题内容

我当前的工作环境是Rails 2.3.8 (导致公司未迁移到Rails 3的各种原因)。我正在尝试通过AJAX调用更新多模型表单的元素-
这个想法是根据用户选择或填写其他字段的方式替换某些下拉菜单。

我以前已经设法通过使用基于非表单的部分来实现此目的-
我现在的问题是,当部分基于form_for和fields_for时,会重现select下拉列表的AJAX更新。

对不起,下面的文字-我已经尝试过尽可能地减少它(代码本身确实可以在我的测试站点上工作)。

如何在爆发控制器中生成表单构建器元素,然后将其传递给category部分以代替identity_form?

任何指针都很棒:D

楷模

class Outbreak < ActiveRecord::Base
        has_many :incidents, :dependent => :destroy
        has_many :locations, :through => :incidents

     accepts_nested_attributes_for :locations, :allow_destroy => true, :reject_if => :all_blank
     accepts_nested_attributes_for :incidents, :allow_destroy => true, :reject_if => :all_blank
end

class Incident < ActiveRecord::Base
    belongs_to :outbreak
    belongs_to :location
    belongs_to :category
    belongs_to :subcategory
    belongs_to :subtype

end

class Location < ActiveRecord::Base
    has_many :incidents, :dependent => :destroy
     has_many :outbreaks, :thorugh => incidents
end

观看次数

_形成

<% form_for(@outbreak, :html => {:multipart => true}) do |form| %>

  <%= render :partial => 'outbreak_type_select', :locals => {:outbreak_types => @outbreak_types, :f => form } %>
   <% form.fields_for :incidents do |incident_form| %>
      <%= render :partial => 'category_select', :locals => {:categories => @categories, :incident_form => incident_form} %>
      <%= render :partial => 'subcategory_select', :locals => { :subcategories => @subcategories, :incident_form => incident_form } %>

   <% end %>
<% end %>

_outbreak_type_select

<% with_str = "'outbreak_type=' + value " %>
<% if @outbreak.id %>
<% with_str << "+ '&id=' + #{outbreak.id}" %>
<% end %>
<%= f.collection_select(:outbreak_type, @outbreak_types, :property_value, :property_value, {}, {:onchange => "#{remote_function(:url  => { :action => "update_select_menus"}, :with => with_str)}"}  ) %>

_category_select

调用update_select_menus之后如何生成事故表单

<%= incident_form.collection_select( :category_id, @categories, :id, :name, {:prompt   => "Select a category"}, {:onchange => "#{remote_function(:url  => { :action => "update_subcategory"}, :with => "'category_id='+value")}"}) %>

RJS

   begin
    page.replace_html 'outbreak_transmission_div', :partial => 'outbreaks/transmission_mode_select', :locals => {:transmission_modes => @transmission_modes }
   rescue
    page.insert_html :bottom, 'ajax_error', '<p>Error :: transmission modes update select</p>'
    page.show 'ajax_error'
   end
   begin
    page.replace_html 'incident_category_select', :partial => 'outbreaks/category_select', :locals => { :categories => @categories }  
   rescue
    page.insert_html :bottom, 'ajax_error', '<p>Error :: incident category update select</p>'
    page.show 'ajax_error'
   end

控制器

暴发

    def new
        @outbreak = Outbreak.new

        @outbreak.incidents.build
        @outbreak.locations.build

        #just the contents for the dropdowns
        @categories = Category.find(:all, :conditions => {:outbreak_type => "FOODBORNE"}, :order => "outbreak_type ASC")
        @subcategories = Subcategory.find(:all, :order => "category_id ASC")

    end

   def update_select_menus
      @outbreak_type = params[:outbreak_type].strip
      if params[:id]
        @outbreak = Outbreak.find(params[:id])
      else
        @outbreak = Outbreak.new
        @outbreak.incidents.build
              @outbreak.locations.build       
      end

      if @outbreak_type == "FOODBORNE"
          ob_type_query = "OUTBREAKS:TRANSMISSION_MODE:" << @outbreak_type
          @transmission_modes = Property.find(:all, :conditions => {:field => ob_type_query})

          ob_type_query = "INVESTIGATIONS:CATEGORY:" << @outbreak_type
          @sample_types = Property.find(:all, :conditions => {:field => ob_type_query})
          @categories = Category.find(:all, :conditions => { :outbreak_type => "FOODBORNE"})
          @subcategories = Subcategory.find(:all, :conditions => { :category_id => @categories.first.id})
          @subtypes = Subtype.find(:all, :conditions => { :subcategory_id => @subcategories.first.id})
      elsif @outbreak_type == "NON-FOODBORNE"
          ob_type_query = "OUTBREAKS:TRANSMISSION_MODE:" << @outbreak_type
          @transmission_modes = Property.find(:all, :conditions => {:field => ob_type_query})

          ob_type_query = "INVESTIGATIONS:CATEGORY:" << @outbreak_type
          @sample_types = Property.find(:all, :conditions => {:field => ob_type_query})
          @categories = Category.find(:all, :conditions => { :outbreak_type => "NON-FOODBORNE"})
          @subcategories = Subcategory.find(:all, :conditions => { :category_id => @categories.first.id})
          @subtypes = Subtype.find(:all, :conditions => { :subcategory_id => @subcategories.first.id})
     end

     respond_to do |format|
          format.html
          format.js
      end

  end

问题答案:

根据http://www.treibstofff.de/2009/07/12/ruby-on-rails-23-nested-attributes-
with-ajax-support/
找到了解决方法

这可能应该放在爆发助手中(在爆发控制器atm中)

    def update_select_menus
      @outbreak_type = params[:outbreak_type].strip
      #next_child_index will only be used if 
      @next_child_index ? params[:next_child_index] : 0
      if params[:id]
        @outbreak = Outbreak.find(params[:id])
      else
        @outbreak = Outbreak.new
        @outbreak.risks.build
        @outbreak.incidents.build
        @outbreak.locations.build

      end

      if @outbreak_type == "FOODBORNE"
          ob_type_query = "OUTBREAKS:TRANSMISSION_MODE:" << @outbreak_type
          @transmission_modes = Property.find(:all, :conditions => {:field => ob_type_query})

          ob_type_query = "INVESTIGATIONS:CATEGORY:" << @outbreak_type

          @sample_types = Property.find(:all, :conditions => {:field => ob_type_query})
          @categories = Category.find(:all, :conditions => { :outbreak_type => "FOODBORNE"})
          @subcategories = Subcategory.find(:all, :conditions => { :category_id => @categories.first.id})
          @subtypes = Subtype.find(:all, :conditions => { :subcategory_id => @subcategories.first.id})


      elsif @outbreak_type == "NON-FOODBORNE"
          ob_type_query = "OUTBREAKS:TRANSMISSION_MODE:" << @outbreak_type
          @transmission_modes = Property.find(:all, :conditions => {:field => ob_type_query})

          ob_type_query = "INVESTIGATIONS:CATEGORY:" << @outbreak_type

          @sample_types = Property.find(:all, :conditions => {:field => ob_type_query})
          @categories = Category.find(:all, :conditions => { :outbreak_type => "NON-FOODBORNE"})
          @subcategories = Subcategory.find(:all, :conditions => { :category_id => @categories.first.id})
          @subtypes = Subtype.find(:all, :conditions => { :subcategory_id => @subcategories.first.id})
     end

     @pathogen_types = Property.find(:all, :conditions => {:field => "PATHOGENS:CATEGORY"})
     @outbreak_types = Property.find(:all, :conditions => {:field => "OUTBREAKS:OUTBREAK_TYPE"} )


     render :update do |page|
         page.replace 'outbreak_transmission_div', :partial => 'transmission_mode_select_update'
         page.replace 'incident_category_select', :partial => 'incident_category_select_update'
         page.replace 'incident_subcategory_select', :partial => 'incident_subcategory_select_update'
         page.replace 'incident_subtype_select', :partial => 'incident_subtype_select_update'
     end

  end

在“爆发”视图中(尽管由于此部分与“事件”相关,所以它可能应该在该视图中显示)

    <% ActionView::Helpers::FormBuilder.new(:outbreak, @outbreak, @template, {}, proc{}).fields_for :incidents,{:child_index => @next_child_index} do |this_form| %>
<div id="incident_category_select">
<%= render :partial => 'category_select', :locals => {:incident_form => this_form } %>
</div>
<% end %>

ActionView :: Helpers :: FormBuilder用于生成所需的fields_for表单-网站文章对此进行了详细介绍。

结果索引由@next_child_index变量设置,该变量可以通过原始AJAX调用传递给控制器​​(例如@next_child_index =
1,那么结果表单元素名称将是 爆发[incidents_attributes] [1] [category_id]
)-我没有在此示例中使用此方法,因为尽管将来我希望该表单在每个爆发中都支持多个位置以进行此初始遍历,但它只接受一个位置-每个爆发均发生一个事件。

_category_select.erb部分(在“爆发”视图atm中)

<% with_str = "'category_id=' + value " %>
<% if @outbreak.id %>
<% with_str << "+ '&id=' + #{@outbreak.id}" %>
<% end %>
<%= incident_form.collection_select( :category_id, @categories, :id, :name, {:prompt   => "Select a category"}, {:onchange => "#{remote_function(:url  => { :action => "update_subcategory"}, :with => with_str)}"}) %>

with_str只是有选择地将爆发ID传递给控制器​​(如果存在)以找到爆发记录以生成表单,如果不存在则创建一个新的爆发以及关联的嵌套属性(如事件和位置)。

必须采用更整洁的方式进行操作-尤其是FormHelper并通过可选的with字符串传递爆发ID。



 类似资料:
  • 本文向大家介绍JQuery 又谈ajax局部刷新,包括了JQuery 又谈ajax局部刷新的使用技巧和注意事项,需要的朋友参考一下 JQuery 再谈ajax局部刷新。 案例: 描述: 1. 点击登录则弹出登录对话框 2. 如果用户名密码不正确,则提示错误信息 3. 当输入信息正确,则刷新登录信息,显示用户名和退出按钮 4. 点击退出弹出提示信息,然后确定后再次刷新用户名,回到了第一幅图片的位置

  • 问题内容: 以下Ajax请求在做什么错…? 链接/通话: 路线: 控制器: 风景: 部分称为: 错误: 看起来Rails正在寻找一个名为“更新”的视图-为什么以及如何解决此问题? 非常感谢!汤姆 问题答案: 好的,对于任何有类似问题的人,我都找到了解决方案: 问题在于,在Rails3中,Prototype被jQuery取代。因此,以下代码不再有效: 以下2个链接将说明有关如何处理jQuery的详细

  • 本文向大家介绍纯JS实现AJAX局部刷新功能,包括了纯JS实现AJAX局部刷新功能的使用技巧和注意事项,需要的朋友参考一下 AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。 AJAX = 异步 JavaScript和XML(标准通用标记语言的子集)。 AJAX 是一种用于创建快速动态网页的技

  • 我们要求当前在SOLR中索引的文档可能需要定期进行部分更新。更新可以是。添加新字段B。更新现有字段的内容。我们模式中的一些字段是存储的,其他的没有。 Solr4确实允许这样做,但必须存储所有字段。见Update a new field to existing document和http://solr.pl/en/2012/07/09/solr-4-0-partial-documents-updat

  • 本文向大家介绍Ajax实现局部刷新的方法实例,包括了Ajax实现局部刷新的方法实例的使用技巧和注意事项,需要的朋友参考一下 前言 最近复习了一下jQuery的一些内容,特此整理一下一些能用的得到的知识点,以前才学jQuery的时候压根就没有注意到那么多的细节,另外最近一直都在整理前端的一些工作中学到的小经验,大概还会有十篇左右的内容,就会慢慢开始整理后端,框架,以及数据库的一些小知识点 一、 Aj

  • 本文向大家介绍极致体验ajax局部和整体刷新,包括了极致体验ajax局部和整体刷新的使用技巧和注意事项,需要的朋友参考一下 本篇文章将向大家介绍如何通过jquery的load方法进行局部刷新,load方法本身很简单,但是想要结合到jfinal和bootstrap的公共项目中,需要我们多加努力了。 首先我先来来说一下方案。 那么我们需要提供ajax请求的回调函数至少两个参数url以及jquery对象