添加 Action 到 Livewire 组件
设置 Livewire 组件
首先,生成新的 Livewire 组件:
php artisan make:livewire ManageProduct
然后,在页面中渲染 Livewire 组件:
@livewire('manage-product')
或者,你可以使用全页 Livewire 组件:
use App\Livewire\ManageProduct;
use Illuminate\Support\Facades\Route;
Route::get('products/{product}/manage', ManageProduct::class);
你必须使用 InteractsWithActions
和 InteractsWithForms
traits,并在你的 Livewire 组件类中实现 HasActions
和 HasForms
接口:
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Livewire\Component;
class ManagePost extends Component implements HasForms, HasActions
{
use InteractsWithActions;
use InteractsWithForms;
// ...
}
添加 Action
添加一个返回 Action 的方法:
use App\Models\Post;
use Filament\Actions\Action;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Livewire\Component;
class ManagePost extends Component implements HasForms, HasActions
{
use InteractsWithActions;
use InteractsWithForms;
public Post $post;
public function deleteAction(): Action
{
return Action::make('delete')
->requiresConfirmation()
->action(fn () => $this->post->delete());
}
// ...
}
最后,你需要在视图中渲染 Action。为此,你需要 {{ $this->deleteAction }}
,将 deleteAction
替换成你自己的 Action 方法名:
<div>
{{ $this->deleteAction }}
<x-filament-actions::modals />
</div>
你也需要 <x-filament-actions::modals />
,在其中注入所需的 HTML 来渲染 Action 模态框。这只需要在 Livewire 组件内引入一次,不论你对该组件有多少次操作。
传递 Action 参数
有时,你可能希望传递参数到你的 Action 中。比如,如果你在同一个视图中渲染同一个 Action 多次,不过每次使用不同模型,你可以传入模型 ID 作为参数,然后稍后对其进行检索。为此,你可以在视图中调用该 Action,并传入以数组方式传入参数:
<div>
@foreach ($posts as $post)
<h2>{{ $post->title }}</h2>
{{ ($this->delete)(['post' => $post->id]) }}
@endforeach
<x-filament-actions::modals />
</div>
现在,你可以在 action 方法中访问该 post ID:
use App\Models\Post;
use Filament\Actions\Action;
public function deleteAction(): Action
{
return Action::make('delete')
->requiresConfirmation()
->action(function (array $arguments) {
$post = Post::find($arguments['post']);
$post?->delete();
});
}
在 Livewire 视图中对 Action 进行分组
通过使用 <x-filament-actions::group>
Blade 组件,传递 actions
数组作为属性,你可以将 Action 分组到一个下拉菜单:
<div>
<x-filament-actions::group :actions="[
$this->editAction,
$this->viewAction,
$this->deleteAction,
]" />
<x-filament-actions::modals />
</div>
你也可以传入任何属性去自定义触发按钮及下拉菜单的外观:
<div>
<x-filament-actions::group
:actions="[
$this->editAction,
$this->viewAction,
$this->deleteAction,
]"
label="Actions"
icon="heroicon-m-ellipsis-vertical"
color="primary"
size="md"
tooltip="More actions"
dropdown-placement="bottom-start"
/>
<x-filament-actions::modals />
</div>
修改 Action
通过调用 replaceMountedAction()
方法,你可以在当前 Action 执行完毕后,将其替换成其他 Action。这样,你就可以链式调用多个 Action:
use App\Models\Post;
use Filament\Actions\Action;
public function editAction(): Action
{
return Action::make('edit')
->form([
// ...
])
// ...
->action(function (array $arguments) {
$post = Post::find($arguments['post']);
// ...
$this->replaceMountedAction('publish', $arguments);
});
}
public function publishAction(): Action
{
return Action::make('publish')
->requiresConfirmation()
// ...
->action(function (array $arguments) {
$post = Post::find($arguments['post']);
$post->publish();
});
}
现在,当第一个 Action 提交后,第二个 Action 会在第一个的地方打开。原本传递到第一个 Action 的参数将会传递到第二个 Action,这样你就可以使用它们在请求间持久化数据。
如果第一个 Action 取消了,第二个就不会打开。如果第二个取消,第一个已经运行过,就不能再取消。