Filament: 如何在表格操作触发后刷新插件
介绍
本文将介绍如何使用 Filament 插件(Widget)创建统计卡片,用来展示用户统计信息。我们将展示如何使用 Livewire 生命周期 hook 和事件,在用户表修改时刷新插件。
安装
首先,安装一个名为 filament-widget-examples 的 Laravel 应用:
laravel new filament-widget-examples
然后使用命令安装 Filament:
cd filament-widget-examples
composer require filament/filament
Filament 推荐添加以下内容到 composer.json
的 post-update-cmd
:
"post-update-cmd": [
// ...
"@php artisan filament:upgrade"
]
编辑用户 Migration 文件:
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->boolean('is_admin');
$table->boolean('is_active');
$table->rememberToken();
$table->timestamps();
});
编辑用户工厂 definition
方法:
//database\factories\UserFactory.php
public function definition()
{
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
'is_admin' => fake()->boolean(),
'is_active' => fake()->boolean(),
];
}
编辑 DatabaseSeeder
的 run
方法:
//database\seeders\DatabaseSeeder.php
public function run()
{
\App\Models\User::factory(100)->create();
}
编辑用户模型:
//app/Models/User.php
protected $fillable = [
'name',
'email',
'password',
'is_active',
'is_admin'
];
运行 migrate 命令:
php artisan migrate --seed
用户资源 User Resource
添加 User Resource 和插件 Widget:
php artisan make:filament-resource User --simple
php artisan make:filament-widget UserOverview --resource=UserResource --stats-overview
编辑用户资源文件:
表单:
//app/Filament/Resources/UserResource.php
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')
->required()
->maxLength(255),
Forms\Components\TextInput::make('email')
->email()
->required()
->maxLength(255),
Forms\Components\Toggle::make('is_admin'),
Forms\Components\Toggle::make('is_active'),
]);
}
表格:
//app/Filament/Resources/UserResource.php
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name'),
Tables\Columns\TextColumn::make('email'),
Tables\Columns\IconColumn::make('is_admin')
->boolean(),
Tables\Columns\IconColumn::make('is_active')
->boolean(),
Tables\Columns\TextColumn::make('created_at')
->date(),
Tables\Columns\TextColumn::make('updated_at')
->date(),
])
->filters([
Tables\Filters\TernaryFilter::make('is_admin'),
Tables\Filters\TernaryFilter::make('is_active'),
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);
}
引入插件
添加 getWidgets
方法:
//app/Filament/Resources/UserResource.php
use App\Filament\Resources\UserResource\Widgets\UserOverview;
public static function getWidgets(): array
{
return [
UserOverview::class,
];
}
添加 getHeaderWidgets
方法:
//app/Filament/Resources/UserResource/Pages/ManageUsers.php
protected function getHeaderWidgets(): array
{
return [
UserOverview::class,
];
}
插件卡片
你可以使用插件卡,在一个插件内展示许多许多不同的统计。编辑用户概览插件:
//app/Filament/Resources/UserResource/Widgets/UserOverview.php
class UserOverview extends BaseWidget
{
protected static ?string $pollingInterval = null;
protected function getCards(): array
{
$usersCount = User::selectRaw('
COUNT(*) as total,
SUM(CASE WHEN is_admin THEN 1 ELSE 0 END) AS admin,
SUM(CASE WHEN is_active THEN 1 ELSE 0 END) AS active
')->first();
return [
Card::make('Total', $usersCount->total)
->color('primary')
->description('Total users'),
Card::make('Admin', $usersCount->admin)
->color('danger')
->description('Admin users'),
Card::make('Active', $usersCount->active)
->color('success')
->description('Active users'),
];
}
}
到浏览器中查看用户资源。其中有三个头部插件:Total users、Admin users 及 Active users.
你可以在用户表中删除用户,表格里的数据更新了,但是这些插件里的信息不会更新。你需要手动刷新才能更新插件。
自动刷新插件
Livewire 生命周期
每个 Livewire 组件都有生命周期。生命周期狗子让你可以在组件生命周期的任意一个地方运行代码。我们可以使用 Updated 钩子,在 Livewire 组件更新后运行。
Livewire 事件监听器
监听器是 key->value 键值对,key 是为监听的事件,值是组件上调用的方法。
我们可以使用 $refresh
魔术操作重新渲染组件。
在 UserOverviewWidget
文件中添加一个监听器:
//app/Filament/Resources/UserResource/Widgets/UserOverview.php
protected $listeners = ['updateUserOverview' => '$refresh'];
updated
钩子方法提供了两个属性:
$name
: 触发的操作的名称。$value
: 触发的操作的值。
我们将使用 $name
属性监听两个表格事件:
mountedTableAction
: 单个删除操作点击后执行。mountedTableBulkAction
: 批量删除操作点击后执行。
然后,我们可以在 updated
方法使用这些名字以及触发 updateUserOverview
事件:
//app/Filament/Resources/UserResource/Pages/ManageUsers.php
public function updated($name)
{
if (Str::of($name)->contains(['mountedTableAction', 'mountedTableBulkAction'])) {
$this->emit('updateUserOverview');
}
}
现在,每次删除操作点击后都会更新插件。
你可以检查表格事件,比如:
//text input in the top right of the table
if (Str::of($name)->contains('tableSearchQuery')) {
...
}
//the table filter form
if (Str::of($name)->contains('tableFilters')) {
...
}