Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/452.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在Rails 4中使用JQuery以一种形式生成嵌套对象_Javascript_Jquery_Ruby On Rails 4 - Fatal编程技术网

Javascript 在Rails 4中使用JQuery以一种形式生成嵌套对象

Javascript 在Rails 4中使用JQuery以一种形式生成嵌套对象,javascript,jquery,ruby-on-rails-4,Javascript,Jquery,Ruby On Rails 4,使用Rails 4,并基于此,我试图通过Javascript使用单个表单动态创建父对象和子对象。我已经修改了Ryan Bate在其应用程序助手中的代码(与railscast插曲在同一页上),以便可以在一个表单中创建父对象(BudgetSegment)和子对象(BudgetRatio) 我希望有人看看我下面的link\u to\u add\u fields方法,告诉我哪里出了问题,因为它不起作用,并告诉我这是否是功能不起作用的罪魁祸首。是否您不能将builder.fields.for嵌套在下面的f

使用Rails 4,并基于此,我试图通过Javascript使用单个表单动态创建父对象和子对象。我已经修改了Ryan Bate在其应用程序助手中的代码(与railscast插曲在同一页上),以便可以在一个表单中创建父对象(BudgetSegment)和子对象(BudgetRatio)

我希望有人看看我下面的
link\u to\u add\u fields
方法,告诉我哪里出了问题,因为它不起作用,并告诉我这是否是功能不起作用的罪魁祸首。是否您不能将
builder.fields.for
嵌套在下面的
f.fields\u中?以下是
application\u helper.rb
中的相关代码:

def link_to_add_fields(name, f, association, nested_association, locals={})
    new_object = f.object.class.reflect_on_association(association).klass.new
    nested_new_object = f.object.class.reflect_on_association(association).klass.reflect_on_association(nested_association).klass.new

    fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
        builder.fields_for(nested_association, nested_new_object, :child_index => "new_#{nested_association}") do |nested_builder|
            render(association.to_s.singularize + "_row", locals.merge!(:ff => builder, :fff => nested_builder))
        end
    end
    link_to_function(name, "add_fields(this, \"#{association}\", \"#{nested_association}\", \"#{escape_javascript(fields)}\")")
end
class BudgetSourcesController < ApplicationController  
  include ApplicationHelper
  require 'debugger'

  def new
    @budget_source = BudgetSource.new
    2.times { @budget_source.budget_sources_genres.build }
    @budget_segment = @budget_source.budget_segments.build
    scenarios.count.times { @budget_segment.budget_ratios.build }
    render 'budget_sources/new'
  end

  def create
    @budget_source = BudgetSource.create(budget_source_params)
    @budget_source.update(:user_id => current_user.id)
    @budget_source.budget_segments.order(:id).each do |bs|
      bs.budget_ratios.order(:id).each_with_index do |br, i|
        br.update(scenario_id: i+1)
      end
    end
    render 'show'
  end

  def show
    @budget_source = BudgetSource.find(params[:id])
    render 'show'
  end


    private

  def budget_source_params
    params.require(:budget_source).permit(:id, :user_id, :name, :description, :territory_id, budget_sources_genres_attributes: [:id, :genre_id, :budget_source_id], budget_segments_attributes: [:id, :max, budget_ratios_attributes: [:id, :box_value, :pa_value, :budget_segment_id, :scenario_id]])
  end
end
这是我的js文件:

function add_fields(link, association, nested_association, content) {
  var new_id = new Date().getTime();
  var regexp = new RegExp("new_" + association, "g")
  var regexp2 = new RegExp("new_" + nested_association, "g")
  $(link).parent().parent().parent().before().child(content.replace(regexp, new_id).replace(regexp2, new_id);
}
BudgetSegment和BudgetRatio都位于表的同一行上。目标是允许用户在单击“添加”按钮时动态创建一行新的文本字段。此行将同时在第一列中创建一个BudgetSegment文本字段,并在右边的列中创建数量不确定的BudgetTio文本字段(对于Javascript方法,我只假设创建了一个BudgetTio,尽管您将在budget\u source\u controller中看到,最初创建了五个BudgetTio)

链接\u添加\u字段
代码应生成以下部分
\u预算\u段\u row.html.erb

<tr  class="table-financial">
    <td><%= ff.text_field :max, :id => "form-currency", :class => "form-control",  :placeholder => '"$1,000,000"', :required => :true %>
    </td>

        <%= ff.fields_for :budget_ratios do |fff| %>     
        <td><%= fff.text_field 'box_value', :class => "form-control", :placeholder => 'e.g., "0.75"' %></td>
        <td><%= fff.text_field 'pa_value', :id => "pa-value", :class => "form-control", :placeholder => 'e.g., "0.75"' %></td>
        <% end %>    
</tr>
如您所见,BudgetRatio块中缺少任何内容

以下是我的模型结构(仅包括相关部分):

下面是预算来源控制者.rb

def link_to_add_fields(name, f, association, nested_association, locals={})
    new_object = f.object.class.reflect_on_association(association).klass.new
    nested_new_object = f.object.class.reflect_on_association(association).klass.reflect_on_association(nested_association).klass.new

    fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
        builder.fields_for(nested_association, nested_new_object, :child_index => "new_#{nested_association}") do |nested_builder|
            render(association.to_s.singularize + "_row", locals.merge!(:ff => builder, :fff => nested_builder))
        end
    end
    link_to_function(name, "add_fields(this, \"#{association}\", \"#{nested_association}\", \"#{escape_javascript(fields)}\")")
end
class BudgetSourcesController < ApplicationController  
  include ApplicationHelper
  require 'debugger'

  def new
    @budget_source = BudgetSource.new
    2.times { @budget_source.budget_sources_genres.build }
    @budget_segment = @budget_source.budget_segments.build
    scenarios.count.times { @budget_segment.budget_ratios.build }
    render 'budget_sources/new'
  end

  def create
    @budget_source = BudgetSource.create(budget_source_params)
    @budget_source.update(:user_id => current_user.id)
    @budget_source.budget_segments.order(:id).each do |bs|
      bs.budget_ratios.order(:id).each_with_index do |br, i|
        br.update(scenario_id: i+1)
      end
    end
    render 'show'
  end

  def show
    @budget_source = BudgetSource.find(params[:id])
    render 'show'
  end


    private

  def budget_source_params
    params.require(:budget_source).permit(:id, :user_id, :name, :description, :territory_id, budget_sources_genres_attributes: [:id, :genre_id, :budget_source_id], budget_segments_attributes: [:id, :max, budget_ratios_attributes: [:id, :box_value, :pa_value, :budget_segment_id, :scenario_id]])
  end
end
class BudgetSourceControllercurrent\u user.id)
@预算|来源.预算|段.订单(:id).每个do | bs|
bs.预算比率.订单(:id).每个带有索引do | br,i的|
br.更新(场景id:i+1)
结束
结束
渲染“显示”
结束
def秀
@budget\u source=BudgetSource.find(参数[:id])
渲染“显示”
结束
私有的
def预算\来源\参数
参数require(:budget\u source)。permit(:id,:user\u id,:name,:description,:territory\u id,budget\u sources\u attributes:[:id,:genre\u id,:budget\u source\u id,:budget\u attributes:[:id,:box\u value,:pa\u value,:budget\u segment\u id,:scenario\u id])
结束
结束

这可能无法解决您的问题,但至少有助于提高可读性。尝试这样做:

new_object = f.const_get(association).new
nested_new_object = f.const_get(nested_association).new
# new_object = f.object.class.reflect_on_association(association).klass.new
# nested_new_object = f.object.class.reflect_on_association(association).klass.reflect_on_association(nested_association).klass.new
然而,我认为可能的问题是你正在传递fff:fff

locals.merge!(:ff => builder, :fff => nested_builder))
您使用的
fff
唯一我能看到的地方就是在这个区块内:

    <%= ff.fields_for :budget_ratios do |fff| %>     
    <td><%= fff.text_field 'box_value', :class => "form-control", :placeholder => 'e.g., "0.75"' %></td>
    <td><%= fff.text_field 'pa_value', :id => "pa-value", :class => "form-control", :placeholder => 'e.g., "0.75"' %></td>
    <% end %> 

“表单控件”:占位符=>'例如,“0.75”%>
“pa值”、:类=>“表单控件”、:占位符=>”例如,“0.75”%>
但正如你所知,块内的fff不是你要经过的
fff
。可能不是错误,但看起来可能是疏忽。也许你想在
f
ff

此外,这里还有一个三重嵌套表单的示例,它将新项添加到表中的偶数。也许有助于了解:

下面是我们用来添加/删除项目的javascript

事件的创建视图:

部分用于底部的add_项,其中包含第三个嵌套。

虽然这不是我想要的解决方案(我真的想知道为什么不能使用builder嵌套对象),但我的快速解决方案是:

我使用
[object].object.association.build
方法创建了一个嵌套对象,而不是将
f.fields\u嵌套在do | f |
块的
fields\u中(与视图中的常规方法相同)

您将注意到一个以
array
开头的新行,因为我想同时创建定义数量的对象,所以我将一个
iterator
变量传递到方法中,该变量基本上只是一个整数。这是我修订的
链接到添加字段
代码:

def add_row(name, f, association, nested_association, iterator)
  new_object = f.object.class.reflect_on_association(association).klass.new
  fields = f.fields_for(association, new_object, child_index: "new_#{association}") do |bs|
    array = eval("iterator.map {bs.object.#{nested_association}.build}")
    render(association.to_s.singularize + "_row", {f: f, ff: bs, fff: array})  
  end      
  link_to_function(name, "add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")")
end

感谢您深入研究代码,不幸的是,它没有解决问题。分部应该生成“fff”本身,但是,这些对象(因为它们最初不是在控制器中构建的)必须单独构建。这就是为什么我在方法中创建它们,并尝试将它们作为本地人推送。
def add_row(name, f, association, nested_association, iterator)
  new_object = f.object.class.reflect_on_association(association).klass.new
  fields = f.fields_for(association, new_object, child_index: "new_#{association}") do |bs|
    array = eval("iterator.map {bs.object.#{nested_association}.build}")
    render(association.to_s.singularize + "_row", {f: f, ff: bs, fff: array})  
  end      
  link_to_function(name, "add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")")
end