高级表单
概述
Filament 表单构造器的设计具有灵活性且可自定义.许多现有的表单构造器允许用户定义表单 Schema,但没有为字段间交互或自定义逻辑提供良好的接口。由于所有 Filament 表单都建立在 Livewire 之上,表单可以动态地适配用户输入,即使在初始化渲染之后也是如此。开发者通过参数注入实时访问许多 utilities,并且基于用户输入创建动态表单。字段的生命周期使用钩子函数开放给扩展,用来定义每个字段的自定义功能。这就允许开发者轻松创建复杂表单。
字段动态响应基础
Livewire 是一个工具,它允许使用 Blade 渲染的 HTML 在不要求整页重载的情况下,动态地重新渲染。Filament 表单是建立在 Livewire 基础上的,因此它们可以动态地重新渲染,以在初始化渲染之后适配它们的布局。
默认情况下,用户使用字段时,表单将不再重新渲染。由于渲染需要往返于服务器,因此这是一种性能优化。但是,如果您希望在用户与字段交互后重新渲染表单,可以使用 live()
方法:
use Filament\Forms\Components\Select;
Select::make('status')
->options([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])
->live()
本例中,用户修改 status
字段的值后,表单会重新渲染。这就允许你基于 status
字段的新值,在表单中对字段进行修改。同时,你也可以深入字段的生命周期,在字段更新时执行自定义逻辑。
动态响应字段失焦
默认情况下,如果字段设为 live()
,表单将在每次字段交互时重新渲染。不过,对于某些字段,比如文本输入,这可能不合适,因为在用户输入区间发送网络请求会导致性能不佳。你可以让表单只有在用户完成字段输入后再重新渲染,也就是表单失去焦点后。使用 live(onBlur: true)
方法可以实现该功能:
use Filament\Forms\Components\TextInput;
TextInput::make('username')
->live(onBlur: true)
动态响应字段防抖
使用 "debouncing",你可以再 live()
和 livewire(onBlur: true)
之间找到一个中间方案。Debouncing(防抖) 将会阻止网络请求,直至用户输入停止一段特定时间。你可以使用 live(debounce: 500)
方法来实现该功能:
use Filament\Forms\Components\TextInput;
TextInput::make('username')
->live(debounce: 500) // Wait 500ms before re-rendering the form.
本例中,500
是发送请求前等待的毫秒数。你可以自定义该数字,甚至使用 '1s'
这样的字符串。
表单组件 utility 注入
用于配置字段和布局组件的绝大多数方法都接受函数作为参数,替代硬编码值:
use App\Models\User;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
DatePicker::make('date_of_birth')
->displayFormat(function () {
if (auth()->user()->country_id === 'us') {
return 'm/d/Y'
} else {
return 'd/m/Y'
}
})
Select::make('user_id')
->options(function () {
return User::all()->pluck('name', 'id');
})
TextInput::make('middle_name')
->required(fn (): bool => auth()->user()->hasMiddleName())
这就解锁了许多自定义的可能。
本包也可以将许多 utilities 作为参数注入到这些函数中。所有接收函数作为参数的自定义方法都可以注入 utilities。
这些注入的 utilities 要求使用特定的参数名。否则 Filament 不会知道注入的是什么。
注入字段的当前状态
如果你想访问字段的当前状态(值),请定义 $state
参数:
function ($state) {
// ...
}
注入当前表单实例
如果你想访问当前组件实例,请定义 $component
参数:
use Filament\Forms\Components\Component;
function (Component $component) {
// ...
}
注入当前 Livewire 组件实例
如果你想访问当前 Livewire 组件实例,请定义 $livewire
参数:
use Livewire\Component as Livewire;
function (Livewire $livewire) {
// ...
}
注入当前表单记录
如果表单与 Eloquent 模型实例相关联,请定义 $record
参数:
use Illuminate\Database\Eloquent\Model;
function (?Model $record) {
// ...
}
注入另一个字段的状态
使用 $get
参数,你也可以在回调函数中检索零一个字段的状态(值):
use Filament\Forms\Get;
function (Get $get) {
$email = $get('email'); // Store the value of the `email` field in the `$email` variable.
//...
}
注入函数设置另一个字段的状态
与 $get
类似的方式,你可以使用 $set
参数,在回调中设置另一个字段的值:
use Filament\Forms\Set;
function (Set $set) {
$set('title', 'Blog Post'); // Set the `title` field to `Blog Post`.
//...
}
当该函数运行时,title
字段的状态将会更新,表单将会使用新 title 重新渲染。这在 afterStateUpdated
方法中很有用。
注入当前表单操作
如果你为面板资源或者关联管理器编写表单,你想检测表单为 create
、edit
或者 view
时,请使用 $operation
参数:
function (string $operation) {
// ...
}
在面板之外,在表单定义中使用
operation()
方法,你可以设置表单的操作。
注入多个 utilities
参数使用反射动态注入,因此你可以以任何顺序联合使用多个参数:
use Filament\Forms\Get;
use Filament\Forms\Set;
use Livewire\Component as Livewire;
function (Livewire $livewire, Get $get, Set $set) {
// ...
}
注入 Laravel 容器的依赖
你也可以注入来自 Laravel 容器的任何东西:
use Filament\Forms\Set;
use Illuminate\Http\Request;
function (Request $request, Set $set) {
// ...
}
字段生命周期
表单的每个字段都有生命周期,即表单加载后,与用户交互以及表单提交后的处理过程。使用各运行阶段的函数,你可以自定义生命周期每个阶段要做的事情。