【问题标题】:Use jQuery to pass an instance from the view to the controller使用 jQuery 将实例从视图传递到控制器
【发布时间】:2014-05-14 00:52:28
【问题描述】:

环境 Ruby 2.0.0、Rails 4.0.3、Windows 8.1、jQuery

编辑:仅供参考,前几天我正在讨论这个问题,我被告知解决这个问题的常用方法就是传递记录 ID。当然,我会在一般情况下推荐该解决方案。在这种情况下,记录正在创建但尚未存储,因此它没有 ID,并且在完成所有必填字段之前无法拥有 ID。

我需要通过 jQuery 将视图中的对象实例传递给控制器​​,以便控制器使用它来使用依赖选择呈现部分。即使我只是传递了一个命名对象的字符串,这个过程通常也能正常工作。但是,现在我必须实现强参数以允许更新,这需要实际实例,而不仅仅是实例的字符串名称。

在 jQuery 中,我使用以下方法获取实例,但这显然是错误的,因为它只获取实例的字符串名称。我认为它可能需要序列化?但是,我只能得到无法序列化的字符串名称。

var car = $('select#car_year_id').attr("car");

基本问题是,如何在 jQuery 中检索 car 的实际实例?或者,我想,问题是,给定 Ruby on Rails 中实例的字符串名称,我如何处理实际实例?任何一个都可能就足够了。当然,其他替代方案将受到欢迎。谢谢。

形式为:

<div class="span8">
  <%= simple_form_for @car,
                      defaults: {label: false},
                      html: {class: 'form-vertical'},
                      wrapper: :vertical_form,
                      wrapper_mappings: {
                              check_boxes: :vertical_radio_and_checkboxes,
                              radio_buttons: :vertical_radio_and_checkboxes,
                              file: :vertical_file_input,
                              boolean: :vertical_boolean
                      } do |f| %>
      <%= f.input(:stock_number, {input_html: {form: 'new_car', car: @car},  autocomplete: :off, placeholder: 'Stock number?'}) %>
      <%= f.input(:year_id, {input_html: {form: 'new_car', car: @car}, collection: Year.all.collect { |c| [c.year, c.id] }, prompt: "Year?"}) %>
      <%= render partial: "makes", locals: {form: 'new_car', car: @car} %>
      <%= render partial: "models", locals: {form: 'new_car', car: @car} %>
      <input type="submit" form="new_car" value="Create Car" class="btn btn-default btn btn-primary">
  <% end %>
</div>

“制造”部分是:

<%= simple_form_for car,
                    defaults: {label: false},
                    remote: true do |f| %>
    <% makes ||= "" %>
    <% if !makes.blank? %>
        <%= f.input :make_id, {input_html: {form: form, car: car}, collection: makes.collect { |s| [s.make, s.id] }, prompt: "Make?"} %>
    <% else %>
        <%= f.input :make_id, {input_html: {form: form, car: car}, collection: [], prompt: "Make?"} %>
    <% end %>
<% end %>

jQuery 是:

$(document).ready(function () {
    // when the #year field changes
    $("#car_year_id").change(function () {
        // make a GET call and replace the content
        var year = $('select#car_year_id :selected').val();
        if (year == "") year = "invalid";
        var form = $('select#car_year_id').attr("form");
        if (form == "") form = "invalid";
        var car = $('select#car_year_id').attr("car");
        if (car == "") car = "invalid";
        $.post('/cars/make_list/',
            {
                form: form,
                year: year,
                car: car
            },
            function (data) {
                $("#car_make_id").html(data);
            });
        return false;
    });
});

控制器动作是:

  def make_list
    makes = params[:year].blank? ? "" : Make.where(year_id: params[:year]).order(:make)
    render partial: "makes", locals: { car: params[:car], form: params[:form], makes: makes }
  end

【问题讨论】:

    标签: javascript jquery ruby-on-rails ruby


    【解决方案1】:

    我找到了答案!好激动!

    有一个新的 HTML 结构允许您对 HTML 元素使用任意属性,只要名称前面带有“data-”即可。例如:

    <%= f.input(:year_id, {input_html: {form: 'new_car', data-car: @car}}, collection: Year.all.collect { |c| [c.year, c.id] }, prompt: "Year?"}) %>
    

    这在 Rails 中是有问题的,因为 Rails 不喜欢符号中的连字符。但是,有一个可选的帮助器使用 data: 符号来传递哈希,如下所示:

    <%= f.input(:year_id, {input_html: {form: 'new_car', data: { car: @car}}, collection: Year.all.collect { |c| [c.year, c.id] }, prompt: "Year?"}) %>
    

    见:Best way to use html5 data attributes with rails content_tag helper?

    然后,在 JavaScript 中,您可以使用 dataset 属性检索 DOMStringMap 对象,如下所示:

    var element = document.getElementById('car_year_id');
    var car = element.dataset.car;
    

    见:HTML5 Custom Data Attributes (data-*)

    这会将汽车作为哈希对象返回,这正是我所需要的!

    帮助很大的总体参考:Rails 3 Remote Links and Forms: A Definitive Guide

    为了完整起见,我曾经使用以下代码将哈希转换回控制器中的对象:

    car_hash = params[:car].gsub!(/":/, '" => ')
    null = nil
    @car = Car.new(eval(car_hash))
    

    【讨论】:

      猜你喜欢
      • 2021-06-14
      • 1970-01-01
      • 2012-06-29
      • 1970-01-01
      • 2012-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多