Rails turbolinks ломают отправку удаленной формы

У меня довольно странная проблема с использованием Rails 4, Turbolinks и удаленной формы. У меня есть форма, похожая на:

<%= form_for [object], remote: true do |f| %>                                                   
    <td><%= f.text_field :name, class: 'form-control' %></td>                                     
    <td><%= f.email_field :email, class: 'form-control' %></td>                                   
    <td><%= f.submit button_name, class: 'btn btn-sm btn-primary' %></td>
<% end %>    

Эта форма добавляет (создает) новый объект. Однако это не всегда работает:

  • Когда я загружаю страницу напрямую, используя URL-адрес или обновление; оно работает
  • Когда я перехожу из своего приложения на эту страницу; это терпит неудачу

При отключении турболинков по этой ссылке страница работала отлично.

У меня есть два вопроса:

  1. Почему это не работает? Это потому, что удаленные обработчики не привязаны к кнопке из-за проблемы с JQuery/Turbolinks?
  2. Как я могу обойти эту проблему?

Заранее спасибо.

Решение

Благодаря @rich-peck решением было добавить фрагмент javascript, который вручную отправляет форму при нажатии кнопки:

<%= javascript_tag do %>
  var id = "#<%= dom_id(f.object) %>";
  var inputs = $(id).parent().find('input');
  console.log(inputs);
  $(id).parent().find('button').on('click', function(e) {
    e.preventDefault();
    $(id).append(inputs.clone());
    $(id).submit();
  });
<% end %>

Этот код добавляет javascript в строку таблицы формы, получает входные данные, добавляет их к идентификатору и отправляет форму. Предотвращение по умолчанию(); предотвращает отправку запроса дважды, когда страница обновляется и форма действительно работает.


person Silox    schedule 09.03.2014    source источник


Ответы (2)


Турболинки

Как уже упоминалось, проблема с Turbolinks заключается в том, что он перезагружает <body> часть DOM с помощью ajax-вызова, то есть JS не перезагружается, так как он находится в голове.

Типичный способ решить эту проблему — delegate JS из document, например:

$(document).on("click", "#your_element", function() {
    //your code here
});

Поскольку document будет присутствовать всегда, он будет постоянно запускать JS.


Удаленное

С вашей проблемой немного сложнее

Проблема в том, что вы полагаетесь на JQuery UJS (ненавязчивый JavaScript) движок Rails, который сложно исправить самостоятельно

У нас никогда не было этой проблемы, и мы все время используем Turbolinks, поэтому я полагаю, что проблема может быть связана с тем, как вы строите свою форму/обрабатываете запрос. Этот GitHub, похоже, воссоздал проблему, и она была связана с таблицей

Может быть, вы могли бы попробовать:

<%= form_for [object], remote: true do |f| %>                                                   
    <%= f.text_field :name, class: 'form-control' %>                                     
    <%= f.email_field :email, class: 'form-control' %>                              
    <%= f.submit button_name, class: 'btn btn-sm btn-primary' %>
<% end %>    
person Richard Peck    schedule 09.03.2014
comment
Спасибо за ваш ответ - форма действительно находится в таблице (мы используем какое-то представление, похожее на excel, с строкой добавления внизу и строками, которые редактируются в строке, так что это тоже будет причиной проблемы Я добавлю кусок Javascript для каждой строки, которая отправляет форму при нажатии на кнопку, чтобы обойти проблему. - person Silox; 09.03.2014
comment
Вы можете попробовать ручной вызов ajax - заполнение данных из определенных элементов? - person Richard Peck; 09.03.2014
comment
Я действительно попробую это и вернусь к вам! - person Silox; 09.03.2014
comment
Спасибо - жду исправления! - person Richard Peck; 09.03.2014
comment
Я действительно исправил это с помощью ручного вызова, я добавил фрагмент кода к своему вопросу. Спасибо! - person Silox; 11.03.2014
comment
Я столкнулся с тем же самым, с Turbolinks 5 и Rails 5, есть ли другой способ обойти это в настоящее время? - person Petros Kyriakou; 06.07.2016
comment
Turbolinks по-прежнему работает так же, просто теперь он использует другие хуки. Если вы разместите вопрос и дайте ссылку на него здесь, я отвечу на него, если хотите! - person Richard Peck; 07.07.2016

Турболинки не полностью перезагружают вашу страницу, а только ее часть. Это то, что делает их такими быстрыми, однако, если у вас есть JavaScript, требующий полной перезагрузки страницы, у вас возникнут проблемы. Причина, по которой это работает с обновлением, заключается в том, что теперь вы принудительно перезагружаете страницу полностью.

Изменить: возможно, стоит попробовать этот драгоценный камень: https://github.com/kossnocorp/jquery.turbolinks

Немного дополнительной информации о внутренней работе турболинков: http://guides.rubyonrails.org/working_with_javascript_in_rails.html#turbolinks

Или: https://github.com/rails/turbolinks

P.S. Также убедитесь, что javascript_include_tag находится внутри тега заголовка (а не в теле)

person rails4guides.com    schedule 09.03.2014
comment
Нет - это в голове. - person Silox; 09.03.2014
comment
Мой javascript_include_tag был на теле... спасибо @rails4guides.com - person rizidoro; 10.05.2014