javascript 在 rails 中提交表单后 6 控制器中的更新操作未启动 update.js.erb

After javascript submits form in rails 6 the update action in controller not launching update.js.erb

不确定我是否问错了这个问题,但我似乎无法准确找到我面临的问题。

我有一个非常基本的 rails 6 任务列表应用程序。任务要么完成要么未完成,change/update 将通过 javascript 完成(html 端工作正常)。

这是我的部分表格 _task.html.erb:

<%= form_with model: task, html: { class: "edit_task", id: "edit_task_#{task.id}" } do |f| %>
  <%= f.check_box :complete %>
  <%= f.submit "Update" %>
  <%= f.label :complete, task.name %>
  <%= link_to "(remove)", task, method: :delete, data: {confirm: "Are you sure?"}, remote: true %>
<% end %>

这里是javascript提交表单,tasks.js

function submit_update(){
    const checkboxes = document.querySelectorAll('.edit_task input[type=checkbox]');
    const submitbutton = document.querySelectorAll('.edit_task input[type=submit]');

    submitbutton.forEach(button => button.remove());

    checkboxes.forEach(checkbox => {
        checkbox.addEventListener('click', () => checkbox.parentElement.submit());
    });
}

window.addEventListener('turbolinks:load', event => {
    submit_update();
    document.addEventListener('task_added', event => submit_update());
});

这部分工作得很好,但是一旦提交并基于控制器的这一部分

  def update
    @task.update!(task_params)
    respond_to do |format|
      format.html { redirect_to root_url, notice: 'Task successfully updated' }
      format.js
    end
  end

我的理解是这应该启动 update.js.erb,目前看起来像

unction update_task() {
  const current_task = document.querySelector('#edit_task_<%= @task.id %>');
  const complete_tasks = document.querySelector('#complete_tasks');
  const incomplete_tasks = document.querySelector('#incomplete_tasks');

  <% if @task.complete? %>
    complete_tasks.insertAdjacentHTML('beforeend',current_task.innerHTML);
  <% else %>
    incomplete_tasks.insertAdjacentHTML('beforeend',current_task.innerHTML);
  <% end %>
}

update_task();

我已经尝试使用警报调用将上面的内容更改为单行,但它仍然没有被调用。

如果有人能告诉我为什么 update.js.erb 没有被调用,我将不胜感激:)

如果需要任何其他信息,请告诉我?

编辑:

在进一步测试中,我发现如果我通过单击按钮提交更新,即通过 javascript 删除提交,update.js.erb 将被正确操作。

所以看起来重点需要放在 tasks.js 文件上以及它是如何提交的? 奇怪的是,当包含它时,提交后 HTML 格式运行正常,而不是 js 格式??

经过数天尝试获得正确的搜索词后,我找到了解决方案并很高兴提交给其他人查找:)

魔法可以找到here

我的例子的变化如下--

    checkboxes.forEach(checkbox => {
        checkbox.addEventListener('click', () => checkbox.parentElement.submit());
    });

// becomes

    checkboxes.forEach(checkbox => {
        checkbox.addEventListener('click', event => {
            checkbox.parentElement.dispatchEvent(new Event('submit', {bubbles: true}));
        });
    });

我已经编辑了 update.js.erb(做了同样的事情只是更干净了一点),但它也 需要为新添加的项目添加一个额外的条目以触发条目更改位置:

$ cat app/views/tasks/update.js.erb 
function update_task() {
  const current_task = document.querySelector('#edit_task_<%= @task.id %>');
  const to_task = document.querySelector('#<%= @task.complete? ? "complete_tasks" : "incomplete_tasks" %>');

  // Remove from previous list
  current_task.remove();

  // Append to the end of new list
  to_task.insertAdjacentHTML('beforeend', '<%= j render(@task) %>');

  // Advise tasks.js that new entry needs listener added
  to_task.dispatchEvent(new Event('task_added', { bubbles: true }));
}

update_task();

希望其他人觉得这有用:)