【问题标题】:Is there a way to regenerate link_to_add_association (specifically data-association-insertion-template)?有没有办法重新生成link_to_add_association(特别是data-association-insertion-template)?
【发布时间】:2017-10-26 19:45:33
【问题描述】:

构建了一个非常基本的 rails 应用程序来使用 cocoon 操作嵌套属性,并且添加和删除链接效果很好。但是,没过多久,我就想更改插入内容的基础内容,例如响应另一个字段更改包含的选择标记中的选项值列表。似乎要添加的内容包含在“a”标签数据元素(数据关联插入模板)中。我可以通过 jQuery 轻松更改所有包含行的选择选项,但更改 link_to_add_association 的行为超出了我的范围。

这是我的示例的 sn-ps:

_form.html.erb

  <div>
    <strong>Entries:</strong>
    <div id="entries" style="border: thin solid">
      <%= f.fields_for :entries do |oi| %>
        <%= render "entry_fields", f: oi %>
      <% end %>
      <div class="links">
        <%= link_to_add_association 'Add Entry', f, :entries, {id: 'cocoon-add-entry'} %>
      </div>
    </div>
  </div>

_entry_fields.html.erb

<div class="nested-fields">
  <%= f.label :item_id %>
  <%= f.select :item_id, @items.collect {|i| [i.style, i.id]}, {include_blank: true}, {selected: :item_id, multiple: false} %>

  <%= f.label :decoration_id, 'Decoration' %>
  <%= f.select :decoration_id, @decorations.collect { |d| [ d.name, d.id ] }, {include_blank: true}, {selected: :decoration_id, multiple: false, class: 'decoration'} %>

  <%= f.label :color %>
  <%= f.text_field :color %>

  <%= f.label :size_id %>
  <%= f.select :size_id, @sizes.collect { |s| [ s.name, s.id ] }, {include_blank: true}, {selected: :size_id, multiple: false} %>

  <%= f.label :number %>
  <%= f.number_field :number, value: 1, min: 1 %>

  <%= f.check_box :_destroy, hidden: true %>

  <%= link_to_remove_association "Remove Entry", f %>
</div>

orders.coffee

ready = ->
  $('.customer').change ->
    $.ajax
      url: '/orders/change_customer'
      data: { customer_id : @value }

$(document).ready(ready)
$(document).on('turbolinks:load', ready)

order_controller.rb

  def change_customer
    @decorations = Decoration.joins(:logo).where('logos.customer_id = ?', params[:customer_id])
    respond_to do |format|
      format.js
    end
  end

change_customer.js.erb

// update all existing entry decorations with new customer driven options
<% new_decor = options_from_collection_for_select(@decorations, :id, :name) %>
var new_decor_options = "<option value='' selected='selected'></option>" + "<%=j new_decor %>";
$('.decoration').html(new_decor_options);

// now need to change $('#cocoon-add-entry').attr('data-association-insertion-template, ???);
// or regenerate link entirely - but don't have required data to do so here (form builder from original)

我曾尝试通过 js str.replace 直接操作模板数据字符串,但这是一个丑陋的正则表达式,因为首先进行了 unescapeHTML 和 htmlsafe 操作以使其成为属性。而且,这种方法对我来说并不好闻。我一直在慢慢研究茧 view_helpers 和 javascript,但似乎没有什么合适的,或者我似乎没有正确的方法/数据值来构建替换链接。有什么建议吗?

顺便说一句,茧宝石的荣誉。

【问题讨论】:

  • 查看允许在插入之前或之后操作要插入(或插入的 html)的回调。检查:github.com/nathanvda/…
  • 感谢您的指导 - 我确实浏览了那篇文章。不幸的是,有一点我不太明白。我相信它恰好属于“在这里做点什么”参考。我想做的是为添加关联链接提供一组新的集合选项。我向服务器发送一个请求以获取它们,然后想要重建链接(但没有原始的 FormBuilder 可在调用 link_to_add_association 时使用)或更改现有 html 中插入模板的这一部分。在示例中,这种更改将如何以及在何处实施?
  • 回调允许使用 javascript 操作要插入的 html,例如更改可用选项列表。恕我直言,这比您现在建议的要干净得多。另外,除此之外:当客户更改时(不在表格中?)是否应该更改所有下拉列表?还是只有新的?
  • 再次感谢。关于更新所有下拉列表的观点是正确的,这实际上是对 change_customer.js.erb 中的所有装饰类选择完成的。 (客户字段只是没有显示在上面的 sn-p 表单中)。事实上,如果需要,我可以使用相同的机制更改因其他字段信息更改而变化的任何选项列表。我遇到的问题是从数据库中获取必要的更改以填充现在通过 ajax 调用完成的新选项列表,但不确定如何在不等待响应的情况下在我的咖啡脚本中使用回调。

标签: javascript jquery ruby-on-rails cocoon-gem


【解决方案1】:

经过大量的咬牙切齿,我拼凑出一个潜在的解决方案。由于限制,我尚未决定是否将其投入生产,但由于结合了几个不同的 SO 问题和答案,以下工作:

change_customer.js.erb

// update all existing entry decorations with new customer driven options
<% new_decor = options_from_collection_for_select(@decorations, :id, :name) %>
var new_decor_options = "<option value='' selected='selected'></option>" + "<%=j new_decor %>";
$('.decoration').html(new_decor_options);

// update the Add Entry link to capture new decorations set.
// Note use of ugly hack to recreate 'similar' form.
// Also note that this will only work for new order; will have to revise for edit.
'<%= form_for(Order.new) do |ff| %>'
$('#cocoon-add-entry').replaceWith("<%=j render partial: 'add_entry_link', locals: {f: ff} %>");
'<% end %>'

_add_entry_link.html.erb

<%= link_to_add_association 'Add Entry', f, :entries, {id: 'cocoon-add-entry', data: {'association-insertion-method' => 'after'}} %>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-07
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    • 2021-11-08
    • 2018-11-10
    • 2020-03-06
    相关资源
    最近更新 更多