“嵌套模型表单”正确添加了新字段,但coffeescript行为不会影响新字段,如页面上的现有字段

时间:2013-09-08 02:14:47

标签: javascript jquery ruby-on-rails ruby coffeescript

我在rails cast中使用嵌套模型表单。 http://railscasts.com/episodes/196-nested-model-form-revised - 这是add_fields coffeescript:

  $('form').on 'click', '.add_fields', (event) ->
    time = new Date().getTime()
    regexp = new RegExp($(this).data('id'), 'g')
    $(this).before($(this).data('fields').replace(regexp, time))
    $(".excelCreator, .videoCreator, .mcCreator").hide()
    event.preventDefault()

我有一组三个单选按钮(“excel”+“video”+“multiple choice”)和一个与每个单独关联的隐藏div。当我点击单选按钮“视频”时,会在名为.videoCreator的div中弹出一些表单。 “excel”和“multiple_choice”的行为相同。

$(".excelCreator, .videoCreator, .mcCreator").hide()
  $(".stepRadio").change ->
    $(".excelCreator, .videoCreator, .mcCreator").hide()
    $container = $(@).closest('.stepCreator')
    $container.find(".excelCreator, .videoCreator, .mcCreator").hide()
    if @value is "video"
      $container.find(".videoCreator").show()
    else if @value is "excel"
      $container.find(".excelCreator").show()
    else if @value is "multiple_choice"
      $container.find(".mcCreator").show()

此处充分说明了此行为:http://jsfiddle.net/ambiguous/2XAP2/

我的问题是,当我点击.add_fields按钮时,上面的行为不再适用于新添加的字段,并且动态创建新表单。我点击添加字段按钮 - 弹出一组新的单选按钮,但是,当我点击三个单选按钮中的任何一个时,它不会显示相关的div(请记住,我隐藏了所有三个div,点击了添加字段按钮 - 如果我不隐藏它们,那么所有三个div一次出现)。但是,在页面上的任何其他字段上,它可以正常工作(只是不在刚刚添加的字段上)。

我尝试将两种行为结合起来,但是这不起作用:

$('form').on 'click', '.add_fields', (event) ->
        time = new Date().getTime()
        regexp = new RegExp($(this).data('id'), 'g')
        $(this).before($(this).data('fields').replace(regexp, time))
      $(".excelCreator, .videoCreator, .mcCreator").hide()
      $(".stepRadio").change ->
        $(".excelCreator, .videoCreator, .mcCreator").hide()
        $container = $(@).closest('.stepCreator')
        $container.find(".excelCreator, .videoCreator, .mcCreator").hide()
        if @value is "video"
          $container.find(".videoCreator").show()
        else if @value is "excel"
          $container.find(".excelCreator").show()
        else if @value is "multiple_choice"
          $container.find(".mcCreator").show()
        event.preventDefault()

任何帮助将不胜感激

1 个答案:

答案 0 :(得分:1)

我猜你只需要使用on的“实时”版本:

  

委托事件的优势在于它们可以处理来自稍后添加到文档的后代元素的事件。通过选择在附加委托事件处理程序时保证存在的元素,您可以使用委派事件来避免频繁附加和删除事件处理程序的需要。例如,此元素可以是模型 - 视图 - 控制器设计中视图的容器元素,如果事件处理程序想要监视文档中的所有冒泡事件,则可以是文档。在加载任何其他HTML之前,文档元素在文档的头部可用,因此可以安全地将事件附加到那里而无需等待文档准备就绪。

而不是直接绑定到change。像这样:

$(document).on 'change', '.stepRadio', ->
  # Same stuff you have in your .change callback

而不是你当前的:

$(".stepRadio").change ->
  #...

这种形式的on监视document上的事件以及更改事件(包括来自新添加元素的事件)将冒出document $(document).on('change', '.stepRadio', ...) id

演示:http://jsfiddle.net/ambiguous/Xk5ZC/

添加更多按钮添加另一个部分,您将看到所有单选按钮继续工作。请注意,该演示无法正确修补for上的单选按钮<label>属性或on属性,真实版本会处理此问题,但这只是一个演示,我不想让它更加混乱,以展示{{1}}的用法。