从ajax提取时加载表单对象

时间:2018-09-19 00:31:48

标签: javascript ruby-on-rails ruby ajax ruby-on-rails-5

我有一个呈现部分“表单”的表单。

= form_for(@booking, :as => :booking, :url => admin_bookings_path, :html => { :multipart => true }) do |f|
  = render partial: "form", locals: { f: f }

再次在部分表单中基于new_record?呈现另一个部分。

- if f.object.new_record?
  #extra-products
    = render partial: 'new_booking_extra_product', locals: { f: f }
- else
  = render partial: 'extra_product', locals: { f: f }

在bookings#new中,当用户选择特定的car_id时,我想通过ajax显示与其相关的产品。为此,我使用了ajax来请求bookings#fetch_extra_product。

# Ajax request to fetch product
$('#booking_car_id').on('change', function(e){
    var selectedCarId = $("#booking_car_id option:selected").val();
    var url = "/admin/bookings/" + selectedCarId + "/fetch_extra_product";

    $.ajax(url,{
      type: 'GET',
      success: function(msg){
      },
      error: function(msg) {
        console.log("Error!!!");
      }
    });
  });

# Bookings#fetch_extra_product
def fetch_extra_product
    @car_id = params[:car_id] || Car.all.order('id desc').first.id
    @extra_product = Car.find(@car_id).extra_products

    respond_to do |format|
      format.js
    end
end

fetch_extra_product.js.erb如下所示:

$('#extra-products').html('$("<%= j render(:partial => 'new_booking_extra_product', :locals => {:f => f}) %>")');

但是在此状态下未定义表单对象(f)。提取对象的最佳方法是解决此问题的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

当您收到Ajax请求时,您将希望在服务器端与关联产品一起呈现部分视图。然后,您可以从该部分发送HTML作为响应的一部分,并使用Ajax success回调将部分视图附加到DOM,但需要使用它。然后,您可以(在您的控制器中)编写如下代码:

def fetch_extra_product

  # Unless you're using @car_id in a view or something, I'd just
  # just use a local variable instead of an instance variable
  #
  car_id = params[:car_id] || Car.all.order('id desc').first.id
  @extra_products = Car.find(car_id).extra_products

  respond_to do |format|
    format.js { render partial: 'extra_products_div', status: :ok }
  end

然后您的部分代码如下:

<div class="extra-products">
  <% @extra_products.each do |product| %>
    <h2><%= product.name %></h2>
    ...
  <% end %>
</div>

这样,您的JavaScript可以遵循以下原则:

$.ajax(url, {
  type: 'GET',
  success: function(msg) {
    $('#foo').attach(msg);
  },
  error: function(msg) {
    console.log('Error!!!');
  }
});

另一条评论:如果您的API仅通过Ajax来获得对此路由的请求,则不需要respond_to块。在这种情况下,您只需将render partial: 'extra_products_div', status: :ok放在您所在的行下 定义@extra_products