Symfony 7.1 AssetMapper问题:JS仅在初始加载或刷新时生效
解决Symfony 7.1 AssetMapper下页面导航后JS不加载的问题
问题原因
Symfony 7.1默认集成了Turbo Drive(Symfony UX Turbo组件),页面间导航通过AJAX异步替换内容而非全页刷新。这种模式下,DOMContentLoaded事件仅在首次加载时触发,后续导航不会再执行该事件绑定的初始化代码,导致DataTables等JS功能无法正常初始化。
解决方案
将初始化逻辑绑定到Turbo提供的turbo:load事件上,该事件会在首次页面加载和每次Turbo导航完成后触发。同时添加实例检查,避免重复初始化DataTable。
修改app.js代码
更新事件监听部分,替换DOMContentLoaded为turbo:load,并增加实例校验:
import './styles/app.css'; import 'datatables.net-dt/css/dataTables.dataTables.min.css'; import './bootstrap.js'; import DataTable from 'datatables.net-dt'; function loadDatatable() { console.log( '%c loadDatatable', 'background: #00FF2E; color: #000000' ); new DataTable( '#users-datatable', { ajax: Routing.generate( 'app_users_ajax' ), processing: true, serverSide: true, columns: [ { data: 'id' }, { data: 'email' }, { data: 'firstName' }, { data: 'lastName' }, { data: 'status' }, { data: 'action', render: function ( data, type, row ) { return `<a href="/?_switch_user=${ row.email }" class="font-bold w-full rounded my-1 bg-primary text-white text-primary-foreground hover:bg-primary-hover py-2 px-3">Impersonate</a>`; }, }, ], } ); } // 使用Turbo的turbo:load事件替代DOMContentLoaded document.addEventListener('turbo:load', function () { const tableElement = document.getElementById('users-datatable'); // 仅当表格存在且未被初始化时执行 if (tableElement && !DataTable.isDataTable(tableElement)) { loadDatatable(); } });
额外注意事项
- 若项目未启用Turbo(极少情况),需检查是否使用了其他页面导航优化方案(如PJAX),替换为对应方案的页面加载完成事件即可。
- 若存在多个需初始化的组件,可统一封装初始化逻辑,在
turbo:load中批量执行,保持代码整洁。
内容的提问来源于stack exchange,提问作者Dimitri G
相关产品推荐
相关产品推荐

