博客

如何表格操作触发后刷新插件

Mar 14, 2023
Martin

介绍

本文将介绍如何使用 Filament 插件(Widget)创建统计卡片,用来展示用户统计信息。我们将展示如何使用 Livewire 生命周期 hook 和事件,在用户表修改时刷新插件。

安装

首先,安装一个名为 filament-widget-examples 的 Laravel 应用:

laravel new filament-widget-examples

然后使用命令安装 Filament:

cd filament-widget-examples
composer require filament/filament

Filament 推荐添加以下内容到 composer.jsonpost-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')) {
...
}