可排序的列表元素仅在排序后响应addClass

时间:2013-11-08 00:02:39

标签: jquery ruby-on-rails jquery-ui jquery-ui-sortable

我通过修改一下Railscast 147教程在Rails 4应用程序中设置了一个Sortable嵌套表单,一切正常。在我的项目中,每个lifields_for包含嵌套资源的字段,包括一个复选框。我的问题是我想根据包含复选框的li的位置来处理复选框信息。另外,如果检查其中一个输入,这也应该影响其他字段。我写了一个jquery函数来执行此操作(主要通过addClassremoveClass),并在可排序和事件处理程序中调用此函数。

  process_components = (o) ->
    $components = $(o).find('li')
    // other stuff
    $components.removeClass("parent_component child_component")
    $components.find('input.is_child').each ->
      firstcheck = $(this).prop('checked')
      secondcheck = $(this).closest('li').next().find('input.is_child').prop('checked')
      if firstcheck is true
        $(this).closest('li').addClass('child_component')
      if firstcheck is false and secondcheck is true
        $(this).closest('li').addClass('parent_component')

$('#components-list').sortable
    axis: 'y'
    items: "> li.component"
    update: ->
      $.post($(this).data('update-url'), $(this).sortable('serialize'))
      process_components $(this)

$('#components-list').on 'click', ':checkbox', (event) ->
    process_components '#components-list'

我的问题是,只有在手动排序列表元素几次之后才能正常工作(元素只有在列表中的位置发生变化后才会响应复选框状态)。我环顾四周,在Google上,但我找不到任何关于为什么会这样的线索。它可能与处理addClass时Jquery和Jquery UI之间的差异有关吗?有想法该怎么解决这个吗?谢谢

1 个答案:

答案 0 :(得分:0)

一天后我发现了,实际上fields_for是罪魁祸首。我不知道它为什么会发生,但检查渲染页面中的各种元素,我发现Rails生成的隐藏:id字段不是作为包含所有其他元素的li的子元素放置的组件字段。相反,隐藏的:id字段最初显示为包含它的li的兄弟,因此process_components定位DOM中的错误元素。在可排序中拖动不同的li之后,建立了正确的DOM结构并且一切正常。因此,解决方案是通过指定f.fields_for(:components, include_id: false)并在<%= f.hidden_field :id %>字段中明确包含fields_for来覆盖Rails默认值。这样,加载页面时一切正常。