AJAX分页列表模态框仅第一页可用问题求助(UIkit3)
这个问题我之前也碰到过,核心原因很简单:UIkit3的组件是在页面初始加载时完成初始化绑定的,而你通过AJAX(remote: true的分页)动态加载的新成员内容(包括模态框和触发按钮),并没有被UIkit重新识别并绑定事件,所以只有第一页的元素能正常工作。
下面给你两个可行的解决方案:
方案一:AJAX更新后手动初始化新组件
这是最直接的修复方式,不需要调整现有结构,只需要修改你的index.js.erb,在DOM更新完成后,让UIkit重新扫描并初始化新添加的元素:
$('#paginator').html('<%= j paginate @members %>'); $('#members').html('<%= j render partial: @members %>'); // 重新初始化新添加的UIkit模态框和toggle按钮 UIkit.init($('#members').find('[uk-modal], [uk-toggle]'));
UIkit的init方法可以接收一个DOM元素集合,它会自动扫描这些元素上的UIkit属性(比如uk-modal、uk-toggle),并完成事件绑定和组件初始化。
方案二:优化HTML结构+AJAX初始化(更规范)
另外注意:你现在把<div uk-modal>直接放在<tbody>里的<tr>旁边,这其实不符合HTML规范(<tbody>只能包含<tr>元素),虽然浏览器可能兼容,但长期来看容易引发其他问题。可以调整结构,把模态框统一放到页面的非表格区域:
- 修改
views/members/index.html.erb,添加一个模态框容器:
<table> <thead> <tr> <th>name</th> <th>modal button</th> </tr> </thead> <tbody id="members"> <%= render @members %> </tbody> </table> <%= paginate @members, window: 2, remote: true %> <!-- 专门存放模态框的容器 --> <div id="member-modals"></div>
拆分成员部分为两个局部视图:
- 新建
views/members/_member_row.html.erb只保留表格行:<tr> <td><%= member.name %></td> <td><button uk-toggle="target: <%= "#modal-member-#{member.id}" %>">OK</button></td> </tr> - 新建
views/members/_member_modal.html.erb单独放模态框:<div id="<%= "modal-member-#{member.id}" %>" uk-modal> <p>Some more random infos about <%= member.name %></p> </div>
- 新建
修改原
views/members/_member.html.erb(或者直接在index里调用拆分后的视图),然后更新index.js.erb:
$('#paginator').html('<%= j paginate @members %>'); // 更新表格行 $('#members').html('<%= j render partial: "member_row", collection: @members %>'); // 更新模态框 $('#member-modals').html('<%= j render partial: "member_modal", collection: @members %>'); // 初始化新的UIkit组件 UIkit.init($('#member-modals').find('[uk-modal]').add($('#members').find('[uk-toggle]')));
这样既修复了模态框的问题,也让HTML结构更规范,减少潜在的兼容性问题。
为什么关闭remote: true就正常?
因为关闭后分页会触发整页面刷新,浏览器重新加载所有DOM元素,UIkit会在页面加载完成时扫描并初始化所有带有UIkit属性的元素,所以所有页面的模态框都能正常工作。而AJAX分页是局部更新DOM,新元素不会被UIkit自动初始化,这就是问题的关键。
内容的提问来源于stack exchange,提问作者dugzino

