Actions
添加 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 的方法。该方法必须与 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 名为 `delete`: // public function delete(): Action // 此方法名无效,因为 Action 名为 `delete`,而非 `deletePost`: // public function deletePost(): Action // ...}
最后,你需要在视图中渲染 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->deleteAction)(['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
如果使用 hidden()
或 visible()
控制 Action 是否渲染,应该此 Action 包装在 @if
中检测其是否可见(isVisible()
):
<div> @if ($this->deleteAction->isVisible()) {{ $this->deleteAction }} @endif {{-- Or --}} @if (($this->deleteAction)(['post' => $post->id])->isVisible()) {{ ($this->deleteAction)(['post' => $post->id]) }} @endif</div>
hidden()
和 visable()
方法也控制着 Action 是否禁用 disabled
,因此如果用户没有权限,它们仍然可以用来保护 Action 不被运行。将此逻辑封装在 Action 自己的 hidden()
或 visible()
中是一种很好的实践,否则你需要在视图和 disabled()
中定义条件。
你还可以利用这一点来隐藏任何在隐藏 Action 时可能不需要渲染的环绕元素:
<div> @if ($this->deleteAction->isVisible()) <div> {{ $this->deleteAction }} </div> @endif</div>
在 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 取消了,第二个就不会打开。如果第二个取消,第一个已经运行过,就不能再取消。
编码触发 Action
有时,你可能需要在用户不点击内置触发按钮的情况下触发操作(Action),尤其是从 JavaScript 中触发。以下是可以在 Livewire 组件上注册的 Action 示例:
use Filament\Actions\Action; public function testAction(): Action{ return Action::make('test') ->requiresConfirmation() ->action(function (array $arguments) { dd('Test action called', $arguments); });}
你可以使用 wire:click
属性,调用 mountAction()
方法,并可选地传入你希望可用的任何参数,在 HTML 中单击触发该操作(Action):
<button wire:click="mountAction('test', { id: 12345 })"> Button</button>
要在 JavaScript 中触发该 Action,你可以使用 $wire
utility,并传入相同的参数:
$wire.mountAction('test', { id: 12345 })
Edit on GitHubStill need help? Join our Discord community or open a GitHub discussion