Rails 6中JS提交表单后update.js.erb未触发问题求助
问题原因分析
当你用原生JavaScript的checkbox.parentElement.submit()提交表单时,并没有触发Rails UJS(Unobtrusive JavaScript)的AJAX提交逻辑。虽然form_with默认会给表单添加data-remote="true"属性,但原生的submit()方法会绕过UJS的事件监听,直接发起普通的HTML表单请求——这就是为什么控制器只会响应HTML格式,而不会执行update.js.erb的核心原因。
而通过按钮提交时,Rails生成的按钮自带UJS绑定,点击时会触发UJS的AJAX处理流程,所以能正常触发JS响应模板。
解决方案
你需要修改JavaScript代码,改用Rails UJS提供的方式触发表单提交,让请求走AJAX流程。这里有两种简单可靠的实现方式:
方式一:用rails.fire触发UJS提交
Rails UJS提供了rails.fire方法,可以触发元素的指定事件并自动带上UJS的处理逻辑。修改你的submit_update函数:
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', () => { // 找到对应表单,用rails.fire触发submit事件,让UJS处理AJAX提交 rails.fire(checkbox.closest('.edit_task'), 'submit'); }); }); }
方式二:直接调用UJS的远程处理函数
如果你不想用rails.fire,也可以直接调用UJS绑定在表单上的远程处理逻辑:
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', () => { const form = checkbox.closest('.edit_task'); // 调用UJS的远程请求处理函数 if (form.dataset.remote !== undefined) { Rails.handleRemote(form); } }); }); }
额外验证提示
可以打开浏览器开发者工具的Network面板,检查提交请求的Accept头:AJAX请求应该会包含text/javascript,而普通HTML请求不会。另外确认你的app/javascript/packs/application.js里已经正确引入并初始化了UJS(Rails 6默认会有import '@rails/ujs'和Rails.start())。
内容的提问来源于stack exchange,提问作者grail
相关产品推荐
相关产品推荐

