在继续之前,请确保 filament/actions 已安装在您的项目中. 您可以通过运行以下命令进行检查:
composer show filament/actions如果尚未安装,请查阅安装指南并根据说明配置各个组件。
首先,生成一个新的 Livewire 组件:
php artisan make:livewire ManagePost然后,将你的 Livewire 组件渲染到页面上:
@livewire('manage-post')或者,你可以使用一个全页面的 Livewire 组件:
use App\Livewire\ManagePost;
use Illuminate\Support\Facades\Route;
Route::get('posts/{post}/manage', ManagePost::class);您必须使用 InteractsWithActions 和 InteractsWithSchemas 特性,并实现 HasActions 和 HasSchemas 接口在您的 Livewire 组件类上:
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Schemas\Concerns\InteractsWithSchemas;
use Filament\Schemas\Contracts\HasSchemas;
use Livewire\Component;
class ManagePost extends Component implements HasActions, HasSchemas
{
use InteractsWithActions;
use InteractsWithSchemas;
// ...
}添加一个返回您的动作的方法。该方法必须与动作具有完全相同的名称,或者名称后跟 Action:
use App\Models\Post;
use Filament\Actions\Action;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Schemas\Concerns\InteractsWithSchemas;
use Filament\Schemas\Contracts\HasSchemas;
use Livewire\Component;
class ManagePost extends Component implements HasActions, HasSchemas
{
use InteractsWithActions;
use InteractsWithSchemas;
public Post $post;
public function deleteAction(): Action
{
return Action::make('delete')
->color('danger')
->requiresConfirmation()
->action(fn () => $this->post->delete());
}
// This method name also works, since the action name is `delete`:
// public function delete(): Action
// This method name does not work, since the action name is `delete`, not `deletePost`:
// public function deletePost(): Action
// ...
}最后, 您需要在您的视图中渲染该操作. 为此, 您可以使用 {{ $this->deleteAction }}, 其中您需要将 deleteAction 替换为您的操作方法的名称:
<div>
{{ $this->deleteAction }}
<x-filament-actions::modals />
</div>您还需要 <x-filament-actions::modals /> 用于注入渲染动作模态框所需的 HTML。这只需在 Livewire 组件中包含一次,无论该组件有多少动作。
filament/actions 也包含以下包:
filament/通知filament/支持这些软件包允许你在 Livewire 组件中使用它们的组件。
例如,如果你的动作使用 通知,记住要在你的布局中包含 @livewire('notifications'),并添加 @import '../../vendor/filament/notifications/resources/css/index.css' 到你的 CSS 文件中。
如果您在操作中使用了任何其他Filament 组件,请务必安装并集成相应的软件包。
有时,您可能希望将参数传递给您的 action。例如,如果您在同一个视图中多次渲染同一个 action,但每次针对不同的模型,您可以将模型 ID 作为参数传递,然后稍后检索它。为此,您可以在视图中调用该 action 并以数组形式传入参数:
<div>
@foreach ($posts as $post)
<h2>{{ $post->title }}</h2>
{{ ($this->deleteAction)(['post' => $post->id]) }}
@endforeach
<x-filament-actions::modals />
</div>现在,你可以在你的动作方法中访问帖子 ID:
use App\Models\Post;
use Filament\Actions\Action;
public function deleteAction(): Action
{
return Action::make('delete')
->color('danger')
->requiresConfirmation()
->action(function (array $arguments) {
$post = Post::find($arguments['post']);
$post?->delete();
});
}如果您使用 hidden() 或 visible() 来控制某个操作是否渲染,您应该将该操作包裹在对 isVisible() 的 @if 检查中:
<div>
@if ($this->deleteAction->isVisible())
{{ $this->deleteAction }}
@endif
{{-- Or --}}
@if (($this->deleteAction)(['post' => $post->id])->isVisible())
{{ ($this->deleteAction)(['post' => $post->id]) }}
@endif
</div>hidden() 和 visible() 方法也控制该操作是否 disabled(),因此如果用户没有权限,它们仍然有助于保护该操作免于运行。将此逻辑封装在操作本身的 hidden() 或 visible() 中是一种良好的实践,否则您需要在视图和 disabled() 中定义该条件。
您也可以利用这一点来隐藏在操作被隐藏时可能无需渲染的任何包装元素:
<div>
@if ($this->deleteAction->isVisible())
<div>
{{ $this->deleteAction }}
</div>
@endif
</div>你可以将操作组合成一个下拉菜单通过使用<x-filament-actions::group> Blade 组件,传入actions数组作为属性:
<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>您可以通过调用 replaceMountedAction() 方法,在当前操作完成后用另一个操作替换它,从而将多个操作串联起来:
use App\Models\Post;
use Filament\Actions\Action;
public function editAction(): Action
{
return Action::make('edit')
->schema([
// ...
])
// ...
->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();
});
}现在,当第一个动作提交时,第二个动作将会在其位置打开。原本传递给第一个动作的参数会传递给第二个动作,因此你可以使用它们在请求之间持久化数据。
如果第一个操作被取消,第二个操作就不会打开。如果第二个操作被取消,第一个操作已经运行,无法取消。
有时您可能需要触发一个操作,而无需用户点击内置的触发按钮,尤其是在 JavaScript 中。 这是一个可以注册到 Livewire 组件上的示例操作:
use Filament\Actions\Action;
public function testAction(): Action
{
return Action::make('test')
->requiresConfirmation()
->action(function (array $arguments) {
dd('Test action called', $arguments);
});
}你可以通过在你的 HTML 中点击来触发该操作,使用 wire:click 属性,调用 mountAction() 方法,并可选地传入任何你希望可用的参数:
<button wire:click="mountAction('test', { id: 12345 })">
Button
</button>要从 JavaScript 触发该操作,你可以使用 $wire 工具,并传入相同的参数:
$wire.mountAction('test', { id: 12345 })