Filament 2中如何从页面向自定义Widget传递数据?
Filament 2中如何从页面向自定义Widget传递数据?
我来给你一步步捋清楚怎么实现这个需求哈,刚好之前我也折腾过类似的场景:
第一步:表单提交后存储图表数据
首先在你的StatsFreelancer自定义页面里,处理表单提交的逻辑,执行完命令拿到图表数据后,得把数据存起来方便后续Widget读取,这里有两种常用方式:
方式1:用页面的Livewire State存储
Filament的自定义页面本身就是Livewire组件,直接用组件的state存数据就行:
protected function getFormActions(): array { return [ Actions\Action::make('submit') ->action(function (array $data) { // 执行命令处理逻辑,拿到图表数据 $chartData = app(YourCommandHandler::class)->handle($data); // 把数据存到页面的state里 $this->state(['chartData' => $chartData]); // 可选:触发事件通知Widget实时更新 $this->dispatch('chartDataReady', $chartData); }) ]; }
方式2:用Session存储
如果需要页面刷新后数据还能保留,就用session来存:
// 表单提交的action里 $chartData = app(YourCommandHandler::class)->handle($data); session()->put('freelancer_stats_data', $chartData);
第二步:让自定义Widget读取数据
接下来处理你的FreelancerStatsChart Widget,让它能拿到咱们刚才存的数据:
对应方式1:从页面State读取+监听事件
在Widget里,通过getPage()方法拿到当前页面,同时监听页面触发的事件实现实时更新:
class FreelancerStatsChart extends Widget { protected static string $view = 'widgets.freelancer-stats-chart'; public ?array $chartData = null; protected $listeners = ['chartDataReady' => 'loadChartData']; public function mount() { // 页面加载时先尝试从页面state拿数据 $page = $this->getPage(); if (isset($page->state['chartData'])) { $this->chartData = $page->state['chartData']; } } public function loadChartData(array $chartData) { // 收到事件后更新数据 $this->chartData = $chartData; } }
对应方式2:从Session读取
如果用了session存储,直接在Widget的mount方法里取就行:
public function mount() { $this->chartData = session()->get('freelancer_stats_data'); // 要是你只需要显示一次数据,用完可以清除session // session()->forget('freelancer_stats_data'); }
第三步:在页面底部展示Widget
最后在StatsFreelancer页面里,把Widget加到底部区域,还可以加个判断,只有有数据的时候才显示:
protected function getFooterWidgets(): array { // 当页面state里有数据时才渲染Widget if (isset($this->state['chartData'])) { return [ FreelancerStatsChart::make(), ]; } // 没有数据时返回空数组,不显示Widget return []; }
第四步:在Widget视图里渲染图表
最后写Widget的Blade视图,比如resources/views/widgets/freelancer-stats-chart.blade.php,直接用$chartData生成图表就行,以Chart.js为例:
@if($chartData) <div> <canvas id="freelancerStatsChart"></canvas> </div> <script> document.addEventListener('livewire:load', function () { const ctx = document.getElementById('freelancerStatsChart').getContext('2d'); new Chart(ctx, { type: 'bar', // 你的图表类型 data: {!! json_encode($chartData) !!}, options: { // 你的图表配置项 } }); }); </script> @else <p class="text-gray-500">请先提交表单获取统计数据</p> @endif
这样一套流程走下来,表单提交后就能在页面底部看到对应的图表啦!
备注:内容来源于stack exchange,提问作者Anemoiaa
相关产品推荐
相关产品推荐

