传递局部变量问题

时间:2014-06-17 03:40:26

标签: javascript jquery ruby-on-rails ruby coffeescript

嗨我有一个rails 4应用程序,我有这个代码:

<%= form_for @store, do |f| %>
  <%= f.fields_for :products do |builder| %>
    <%= render "product_fields",  f: builder %>
  <% end %>
  <%= link_to_add_fields "Add Product", f, :products  %>
<% end %>

然后我有 _product_fields.html.erb 之类的:

<%= f.select :type_of, %w[Blah blah], {}, class: "select_it" %>
<div class='product-view'>
   <%= render "stores/product_form/bookshelf", f:f %>
</div>

我的javascript(coffeescript)看起来像:

$('form').on 'change', '.select_it', (e) ->
   value = $(this).val()
   params = 'type=' + value
   $.ajax({
     url: "/switch_product",
     data: params
   })

然后我的控制器看起来像:

def switch_product
  @type = params[:type]
  respond_to do |format|
    format.js
  end
end

然后我有一个 switch_product.js.erb 文件,如下所示:

$(this).(".product-view").html("<%= j render "stores/product_form/#{@type.downcase}", f:f %> ");

但是在switch_product.js.erb上我收到错误:

undefined local variable or method `f'

如何将局部变量从页面传递到js.erb文件?

编辑:

这是我想用switch_product.js.erb渲染的东西(但这只是一个,我也有_books.html.erb和_bookshelf.html.erb:

<%= f.hidden_field :the_type_is, value: "Birdhouse" %>
  <%= f.fields_for :product_fields, f.object.product_fields.build do |builder| %>
  <%= builder.text_area :price %>
<% end %>

3 个答案:

答案 0 :(得分:0)

您的错误来自于.js.erg:

  <%= j render "stores/product_form/#{@type.downcase}", f:f %>

最后的f:f。你想在那里做什么?

答案 1 :(得分:0)

看起来switch_product.js.erb是从与前面文件不同的控制器操作呈现的。如果是这样的话,这将不起作用。您在第一个操作中的HTML呈现期间实例化构建器,并且一旦完成呈现该页面,构建器已超出范围并被传递到Ruby垃圾收集器。

您需要重新渲染整个表单,一直到第一个文件中的<%= form_for @store, do |f| %>内容。您没有提供该文件的文件名,所以让我们说show.html.erb

我所做的基本上是将所有这些移至_product_form.html.erb(除非它已经是部分的),然后更改switch_product.js.erb以呈现该部分:

$(this).(".product-view").html("<%= j render(partial: 'product_form') %>");

假设整个表单最初位于.product-view下,它将替换整个表单。可能会有一些特定于您的应用的详细工作,但这应该会让您朝着正确的方向前进。

答案 2 :(得分:0)

问题是您正在尝试在js.erb文件的部分内部传递表单构建器。你不能这样做。当您通过ajax调用提交表单时,控件将移至控制器内的ajax方法,并且表单构建器的范围也已完成

如果你在js.erb文件中查看你的代码:

$(this).(".product-view").html("<%= j render "stores/product_form/#{@type.downcase}", f:f %> ");

有两个问题:

一个。 this关键字已失去其范围,因此您无法在此处使用它。要修复需要指定该元素的ID或类

湾您的表单构建器f也已失去其范围,因此而不是呈现表单的一部分,您需要自己呈现整个表单

而不是呈现此部分

<%= f.hidden_field :the_type_is, value: "Birdhouse" %>
<%= f.fields_for :product_fields, f.object.product_fields.build do |builder| %>
  <%= builder.text_area :price %>
<% end %>

您需要呈现此内容:

<%= form_for @store, do |f| %>
  <%= f.fields_for :products do |builder| %>
    <%= render "product_fields",  f: builder %>
  <% end %>
  <%= link_to_add_fields "Add Product", f, :products  %>
<% end %>