Laravel Filament轮询添加音效:无法捕获轮询事件
解决Laravel Filament表格新增行时仅提醒当前用户播放音效的问题
问题分析
你当前的代码无法捕获轮询事件的核心原因:
Livewire.hook('message.processed')触发范围过广,且未匹配Filament表格的专属更新时机- 依赖表格
innerHTML对比易因样式、渲染细节变化误触发,同时DOM初始化时机滞后可能导致表格元素获取失败
修正方案
1. 组件类新增获取最新记录标识的方法
在你的Filament Widget组件类中添加公共方法,通过数据层面判断新增记录,避免依赖DOM内容:
// 你的Widget组件类 public function getLatestRecordId() { // 替换为你的模型查询逻辑,获取最新记录的唯一ID return $this->table->query()->latest('created_at')->value('id') ?? 0; }
2. 修改自定义视图的JS代码
使用Filament专属的表格更新事件filament-table::updated,结合Livewire调用组件方法精准检测新增记录:
<div class="grid w-full" style="--cols-default: repeat(1, minmax(0, 1fr)); --cols-lg: repeat(1, minmax(0, 1fr));"> {{ $this->table }} </div> @script <script> document.addEventListener('livewire:initialized', async function() { // 初始化存储最新记录ID let storedLatestId = {{ $this->getLatestRecordId() }}; sessionStorage.setItem('latestRecordId', storedLatestId); // 监听Filament表格更新事件 document.addEventListener('filament-table::updated', async function(event) { // 仅响应当前组件的表格更新 if (event.detail.table.id !== '{{ $this->getId() }}') return; // 通过Livewire调用组件方法获取最新记录ID const currentLatestId = await $wire.call('getLatestRecordId'); storedLatestId = parseInt(sessionStorage.getItem('latestRecordId')); // 检测到新增记录时播放音效 if (currentLatestId > storedLatestId) { const audio = new Audio("{{ asset('notif.wav') }}"); try { await audio.play(); } catch (err) { console.error('音效播放失败:', err); } // 更新存储的最新ID sessionStorage.setItem('latestRecordId', currentLatestId); } }); }); </script> @endscript
3. 额外注意事项
- 浏览器自动播放限制:现代浏览器要求用户与页面有交互(如点击)后才能自动播放音频,可在页面加载时添加提示,或在用户首次交互后初始化音频对象
- 音效路径验证:确保
{{ asset('notif.wav') }}指向正确的音频文件位置,可在浏览器控制台检查资源加载状态 - 轮询频率调整:根据业务需求修改
->poll('2s')的间隔,避免过于频繁的请求影响性能
内容的提问来源于stack exchange,提问作者M. Rivaldi Anwar Putra
相关产品推荐
相关产品推荐

