使用jQuery-ujs的Rails中新增记录后删除时Unobtrusive-JS函数不触发
问题分析与解决方案
你遇到的是动态DOM元素事件绑定的典型问题——咱们一步步拆解:
问题根源
你在$(document).ready()里直接给[data-js-tutorial-id]元素绑定了ajax:success事件,但这个绑定只对页面初始加载时就存在的DOM元素生效。通过AJAX新增的<li>是后续动态生成的,根本没被绑定这个事件,所以点击Delete按钮时前端JS没反应,但控制器的destroy动作已经执行了,所以刷新后记录就没了。
解决办法:用事件委托搞定动态元素
事件委托是利用事件冒泡机制,把事件绑定到一个始终存在的父元素上(比如你的#tutorials列表容器),不管子元素是一开始就有还是后来动态加的,事件都会被父元素捕获并处理。
修改你的application.js代码:
$(document).ready(function() { // 新增表单的AJAX逻辑保持不变 $('[data-js-tutorial-form]').on("ajax:success", function(event, data, status, xhr){ var tutorial = $(xhr.responseText).hide(); $('#tutorials').append(tutorial); tutorial.fadeIn(2000); }); // 把事件绑定到父容器#tutorials,委托给[data-js-tutorial-id]元素 $('#tutorials').on("ajax:success", "[data-js-tutorial-id]", function(event, data, status, xhr){ var tutorial_id = xhr.responseJSON.id; $('[data-js-tutorial-id=' + tutorial_id + ']').hide(); // 更简洁的写法:直接操作当前触发事件的元素 // $(this).hide(); }); });
额外优化
其实你完全不用通过ID查找元素,因为触发ajax:success的就是那个要删除的<li>本身,直接用$(this)就能操作,既省了DOM查询步骤,代码也更简洁:
$('#tutorials').on("ajax:success", "[data-js-tutorial-id]", function(event){ $(this).hide(); // 直接隐藏当前li元素 });
为什么刷新后就正常?
刷新页面时,所有tutorial都是服务器渲染的初始DOM元素,$(document).ready()里的事件绑定会覆盖这些元素,所以点击Delete时JS逻辑能正常跑起来。
内容的提问来源于stack exchange,提问作者desertNomady
相关产品推荐
相关产品推荐

