Rails 4 и Cocoon gem - не удается получить обратный вызов для запуска имени класса глубоко вложенных полей

У меня есть гем Cocoon, который хорошо работает для добавления и удаления вложенных полей на разной глубине. У меня также есть обратные вызовы after-insert и after-remove, работающие на первом уровне вложенности с использованием идентификатора. Я не могу заставить его срабатывать на втором уровне, используя имя класса, которое я использую, потому что будет несколько наборов этого вложенного набора полей.

views/car_buyers/_form.html.haml

...
#cars
  = f.simple_fields_for :cars do |c|
    = render 'car_fields', f: c
  .link-add
    = link_to_add_association '  + Add a Car', f, :cars, partial: 'car_fields'
...

views/car_buyers/_car_fields.html.haml

.nested-fields.car
  ...
  .upgrade-options
    = f.simple_fields_for :upgrade_options, do |uo|
      = render 'upgrade_option_fields', f: uo

    .link-add
      = link_to_add_association '  + Add an Upgrade Option', f, :upgrade_options, partial: 'upgrade_option_fields'
  ...

views/car_buyers/_upgrade_option_fields.html.haml

.nested-fields.upgrade-option
  = f.input :upgrade_option_type,  label:         'Upgrade Option',
                                   collection:    @upgrade_options_list,
                                   include_blank: 'Select...',
                                   input_html:   { class: 'upgrade-option-type-select input-upgrade-option' },
                                   error:         'Upgrade Option selection required.'

  = f.input :upgrade_option_value, label:         'Upgrade Option Value',
                                   collection:    @upgrade_option_values_list,
                                   include_blank: 'Select...',
                                   input_html:   { class: 'upgrade-option-value-select input-upgrade-option' },
                                   error:         'Upgrade Option Value selection required.'

  .link-remove
    = link_to_remove_association icon('remove'), f, class: 'upgrade-option-remove-link remove-link'

assets/javascripts/car_buyers.js

$(document).ready(function() {

  ...

  $('#cars').on('cocoon:after-insert', function() {
    // this is working
    ...
  }).on('cocoon:after-remove', function() {
    // this is also working
    ...
  });

  ...

  $('.upgrade-options').on('cocoon:before-insert', function() {
    // this is NOT working
    ...
  });

  ...

});

Не использую турболинки, если это имеет значение. Дважды проверил разметку, чтобы убедиться, что идентификатор/классы верны. Кажется, есть что-то основное, что мне не хватает.

Спасибо.


person eggroll    schedule 22.03.2016    source источник


Ответы (2)


Ваш ответ полностью правильный.

Но так как это всего лишь стандартный jquery, вы также можете добавить селектор в обработчик событий, в котором вы можете просто написать его один раз. Итак, что-то вроде:

$('#cars').on('cocoon:before-insert', '.upgrade-options', function() { ...
person nathanvda    schedule 23.03.2016

Итак, я некоторое время занимался этой проблемой, и, конечно же, в ту минуту, когда я задал вопрос, я понял проблему. Поскольку эти обратные вызовы находятся внутри $(document).ready(function() {}), #cars будет существовать в DOM, поэтому его обратные вызовы могут быть связаны. Но поскольку .upgrade-option вложен более глубоко, внутри #cars, он не существует в DOM до тех пор, пока не будет добавлен автомобиль.

Мое решение состояло в том, чтобы вложить обратный вызов $('.upgrade-options').on('cocoon:before-insert', function() {...}) в обратный вызов $('#cars').on('cocoon:after-insert', function() {...}), поскольку после добавления автомобиля в DOM будет существовать .upgrade-option, к которому можно привязать обратный вызов.

assets/javascripts/car_buyers.js — ПЕРЕСМОТРЕННО

$(document).ready(function() {

  ...

  $('#cars').on('cocoon:after-insert', function() {
    // this is working
    ...
    $('.upgrade-options').on('cocoon:before-insert', function() {
      // this is NOW working
      ...
    });
  }).on('cocoon:after-remove', function() {
    // this is also working
    ...
  });

  ...

});
person eggroll    schedule 22.03.2016