【问题标题】:Calling coffeescript in rails form以rails形式调用coffeescript
【发布时间】:2016-02-16 23:05:33
【问题描述】:

我有这个用于动态选择框的咖啡脚本,仅在模型选择框中显示与在品牌选择框中选择的品牌相关的那些模型。 而且我会有多个字段分别使用这个函数,所以匿名函数不会工作。

Coffeescripts 看起来像这样

../assets/javascripts/diys.coffee

DynamicSelect = (makesSelect, modelsSelect) ->
  $(document).on 'change', makesSelect, (evt) ->
    $.ajax 'update_make_models',
      type: 'GET'
      dataType: 'script'
      data: {
        make_id: $("'makesSelect' option:selected").val()
      }
      error: (jqXHR, textStatus, errorThrown) ->
        console.log("AJAX Error: #{textStatus}")
      success: (data, textStatus, jqXHR) ->
        console.log("Dynamic make select OK!")

../views/diys/update_make_models.coffee

$(modelsSelect).empty()
    .append("<%= escape_javascript(render "make_models/make_model") %>")

这是我的表单的一部分,它会重复多次,只有 id 会改变,我将把它作为参数传递给“DynamicSelect”函数。那么我需要在哪里和什么地方才能正确启动这个功能呢?

<div class="vehicle_field">
    <%= f.fields_for :attached_vehicles do |av| %>
    <p>Select make</p>
    <%= av.select :make, options_for_select(@makes.collect { |m| [m.make_name, m.id] }), { include_blank: "Select make" }, { id: 'makes_select1' } %><br>
    <p>Select model</p>
    <%= av.select :model, (render "make_models/make_model"), {prompt: "Select model"}, { id: 'models_select1' } %><br>
    <p>Select years</p>
    <%= av.select :start_year, (Time.now.year + 1).downto(Time.now.year - 100).to_a, prompt: "Year (from)" %>
    <%= av.select :end_year, (Time.now.year + 1).downto(Time.now.year - 100).to_a, prompt: "Year (to)" %><br>
    <% end %>
</div>

------------------------------------------ -------------------------------------------------- -------------------------------------- 编辑,尝试按照 Richard Peck 的建议完成具有 data-remote 属性的动态选择框

在控制台中,当在 make 选择框中选择 make 时,我似乎在参数中得到了正确的“make_id”,但我找不到将它传递给控制器​​ @models 变量的方法,我做对了吗?

用于从视图中选择附加车辆的窗体部件

<div class="vehicle_field">
    <%= f.fields_for :attached_vehicles do |av| %>
    <p>Select make</p>
    <%= av.select :make, (@makes.collect { |m| [m.make_name, m.id] }), { include_blank: "Select make" }, { data: { remote: true, url: "update_make_models", name: "make", update: "#diy_attached_vehicles_attributes_0_model"} } %><br>
    <p>Select model</p>
    <%= av.collection_select :model, @models, (render "make_models/make_model"), {prompt: "Select model"} %><br>
    <p>Select years</p>
    <%= av.select :start_year, (Time.now.year + 1).downto(Time.now.year - 100).to_a, prompt: "Year (from)" %>
    <%= av.select :end_year, (Time.now.year + 1).downto(Time.now.year - 100).to_a, prompt: "Year (to)" %><br>
    <% end %>
</div>

_make_model.html.erb 部分

<% @models.collect do |models| %>
    <option value="<%= models.id %>"><%= models.make_model_name %></option>
<% end %>

diys_controller 中的新操作

def new
  @diy = Diy.new
  @step = @diy.steps.new
  @attached_vehicle = @diy.attached_vehicles.new
  @step.add_images_to_steps.new
  @makes = Make.all
  @models = MakeModel.where("make_id = ?", params[:make])
end

还删除了咖啡脚本和编辑的路线

get '/diys/update_make_models', to: 'diys#new', as: 'update_make_models'

这就是我在选择 make 后在控制台中得到的内容

Started GET "/diys/update_make_models?diy%5Battached_vehicles_attributes%5D%5B0%5D%5Bmake%5D=12" for ::1 at 2016-02-17 20:03:21 +0200
Processing by DiysController#new as JS
  Parameters: {"diy"=>{"attached_vehicles_attributes"=>{"0"=>{"make"=>"12"}}}}
  Make Load (1.0ms)  SELECT "makes".* FROM "makes"
  MakeModel Load (1.0ms)  SELECT "make_models".* FROM "make_models" WHERE (make_id = NULL)
  Rendered make_models/_make_model.html.erb (3.0ms)
  Rendered diys/_form.html.erb (151.0ms)
  Rendered diys/new.html.erb within layouts/application (260.0ms)
Completed 200 OK in 451ms (Views: 446.4ms | ActiveRecord: 2.0ms | Solr: 0.0ms)

【问题讨论】:

    标签: javascript jquery ruby-on-rails coffeescript


    【解决方案1】:

    您可以将.on 绑定到元素本身:

    #app/assets/javascripts/application.coffee   
    $(document).on "change", "select#makes_select1", (evt) ->
      $.ajax 'update_make_models',
        type: 'GET'
        dataType: 'script'
        data:
          make_id: $(this).find("option:selected").val()
        error: (jqXHR, textStatus, errorThrown) ->
            console.log "AJAX Error: #{textStatus}"
        success: (data, textStatus, jqXHR) ->
            console.log "Dynamic make select OK!"
    

    data-remote attribute for select boxes

    = f.collection_select :attribute, @collection, :id, :name, {}, { data: {remote: true, url: "update_make_models"} }
    

    这会将变量params[:object][:attribute] 传递给data-url,您可以在控制器中对其进行管理以提取所需的数据。

    使用上面的代码将使您不再需要在 JS 中定义 ajax

    【讨论】:

    • 我以前是这样的,当我只有一个字段用于附加车辆时,但现在我将拥有许多这样的字段,我将不得不多次编写相同的代码,只更改元素 id ,就没有别的办法了吗?
    • 你实际上可以做一些很酷的事情,让我更新答案
    • 是的,也许这是最好的方法,尝试让它现在工作几个小时,但无法弄清楚。在控制台中,似乎我在选择 make 时在参数中得到了正确的 make id,但不能将它传递给 @models 变量。编辑了我的问题,如果你能检查我做错了什么会很好:)
    • 你需要在你的控制器中调用params[:diy][:attached_vehicles_attributes][0][:make]
    猜你喜欢
    • 2012-03-04
    • 2017-04-16
    • 2013-06-28
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    相关资源
    最近更新 更多