表单重新加载后的Cocoon回调

时间:2014-09-25 16:10:44

标签: ruby-on-rails cocoon-gem

我正在创建一个表单,用户可以在其中添加许多嵌套问题,每个问题可以有多个嵌套答案,其他字段都有ActiveRecord验证器,当它们失败时,页面会重新加载,插入的字段仍然存在。

不会重新加载所有回调(例如cocoon:before-insert),例如插入对象下拉列表的更改处理程序

如果在服务器端验证器上重新加载页面失败,我该怎么做才能使这些回调得到尊重?

另一方面,代码质量明智的是,将一个cocoon回调中创建的处理程序添加到调用控制器上的new方法时构建的嵌套对象的最佳方法(即不是受插入/插入前插入回调影响)?

以下是一些示例coffeescript代码以供澄清:

$(document).ready ->
  $('#questions').on("cocoon:after-insert", (e, added_question) ->
    added_question.find('#type').change ->
      if $(this).val() is "1"
        added_question.find("#answers").hide()
      else
        added_question.find("#answers").show()

编辑:改变了问题,因为删除问题是缺乏正确的包装类

编辑#2:添加了示例代码

1 个答案:

答案 0 :(得分:1)

使用rails4时,您使用的是turbolinks,而您无法再依赖document.ready事件,而应该收听page:change事件。

所以你的代码会变成:

$(window).bind 'page:change', () ->
  $('#questions').on("cocoon:after-insert", (e, added_question) ->
    added_question.find('#type').change ->
      if $(this).val() is "1"
        added_question.find("#answers").hide()
      else
        added_question.find("#answers").show()

或者你可以写$(document).on 'page:change', () -> ...这是完全相同的。

[更新:替代解决方案]

我还没有真正阅读过事件处理程序:)一些评论:

  • 您可能需要尝试使用before-insert。那可能有用。
  • 其次,您使用的是 id #type,但会有多个页面?那就是要求麻烦:)如果你得到的不止一个,请使用一个班级。另外,请使用更具描述性的名称。

有一个更简单的解决方案:jquery可以动态绑定,因此您可以编写

$('#questions').on 'change', '.question-type', () -> 
  var this = $(this)
  var question = $(this).parent('.your-question-class')
  question.toggle()

不确定您是否确实需要检查值,只是切换可见性?

这段代码当然没有经过测试,但我希望你能得到它。查找jquery on处理程序,它允许使用选择器捕获事件。因此,在这种情况下,#questions div内的任何更改事件,对于具有类question-type的元素(而不是您的错误#type id)将由此处理程序处理。它将通过动态,因为它附加到容器元素。因此,如果添加或删除问题,它仍然有效。