Rails中table内button_tag在Ajax重载后失效问题求助
解决Ajax重载后表格内form按钮失效的问题
这个问题的核心是事件绑定丢失:当你通过Ajax重新渲染表格时,原表格内的DOM元素被完全替换,而Rails UJS(Unobtrusive JavaScript)或你绑定的表单提交事件,只在页面初始加载时绑定到当时存在的元素上——新生成的按钮元素没有继承这些事件绑定,所以点击后毫无反应。而link_to能正常工作,是因为它的点击属于浏览器默认的链接跳转行为,不需要额外的事件绑定(除非你加了remote: true,但这里看起来没有)。
下面给你几个可行的解决方案:
方案1:使用事件委托(推荐)
把表单的提交事件绑定到一个不会被Ajax替换的父元素上(比如表格容器#todaysarticles甚至document),利用事件冒泡机制,让新添加的元素也能触发事件。
在你的全局JS文件(比如application.js)里添加这段代码:
// 绑定到持久存在的父元素,覆盖后续Ajax加载的新表单 $(document).on('submit', '.toggle', function(e) { // 让Rails UJS处理表单的异步提交逻辑 Rails.fire(this, 'submit'); e.preventDefault(); });
或者更简单的方式:在index.js.erb渲染完成后,触发Rails UJS的绑定事件,让它重新识别新元素:
$("#todaysarticles").html("<%= escape_javascript(render(:partial => 'todaysarticles')) %>"); // 触发绑定事件,让UJS重新处理新DOM元素 $(document).trigger('rails:attachBindings');
方案2:明确开启表单的UJS支持
如果你的表单是异步提交的,在form_for里明确加上remote: true,确保Rails UJS主动监听这个表单的提交事件,哪怕是新生成的表单:
<%= form_for article, html: {class: 'toggle'}, remote: true do |f| %> <%= f.hidden_field :disable, value: true %> <%= button_tag type: 'submit', class: "btn-mini" do %> <i class="fa fa-eye-slash" aria-hidden="true"></i> <% end %> <% end %>
方案3:直接给按钮绑定点击事件
如果你不想用事件委托,也可以在局部视图里给按钮添加点击事件,每次渲染时重新绑定:
<%= button_tag type: 'button', class: "btn-mini" do %> <i class="fa fa-eye-slash" aria-hidden="true"></i> <% end %> <script> // 每次渲染局部视图时,给当前按钮绑定提交表单的逻辑 $(this).find('.btn-mini').off('click').on('click', function() { $(this).closest('form').submit(); }); </script>
注意这里用off('click')先清理旧事件,避免重复绑定导致多次提交。不过这种方式不如事件委托简洁可靠。
总结来说,最推荐方案1的事件委托或触发rails:attachBindings,它们能完美适配Ajax动态生成元素的场景。
内容的提问来源于stack exchange,提问作者Dark Knight
相关产品推荐
相关产品推荐

