自定义字段
视图字段
除了创建自定义字段,你可以创建 "view" 字段,允许你在不使用额外的 PHP 类的情况下,创建自定义字段。
use Filament\Forms\Components\ViewField;
ViewField::make('rating')
->view('filament.forms.components.range-slider')
这假定你有一个 resources/views/filament/forms/components/range-slider.blade.php
文件。
自定义字段类
你可以创建自定义的字段类和视图,使之可以在整个应用中重用,甚至将其作为插件发布到社区。
如果你只是创建一个使用一次的简单自定义字段,你可以使用视图字段来渲染自定义 Blade 文件。
要创建自定义字段类和视图,请使用如下命令:
php artisan make:form-field RangeSlider
该命令将会创建如下字段类:
use Filament\Forms\Components\Field;
class RangeSlider extends Field
{
protected string $view = 'filament.forms.components.range-slider';
}
同时会新建一个 resources/views/filament/forms/components/range-slider.blade.php
视图文件。
字段工作原理
Livewire 组件是将状态(state)存储在用户浏览器中的 PHP 类。当发起网络请求时,将状态发送给服务器,并填入到 Livewire 组件类的公共属性中,在那里可以像 PHP 中的任何其他类属性一样访问它。
假设 Livewire 组件中有一个公共属性叫做 $name
。你可以以两种方式将该属性绑定到 Livewire 组件的 HTML 输入框字段中:使用 wire:model
属性,或者 使用 Alpine.js 的 entangling:
<input wire:model="name" />
<!-- Or -->
<div x-data="{ state: $wire.entangle('name') }">
<input x-model="state" />
</div>
当用户输入到输入框中时,$name
属性 会在 Livewire 组件类中更新。用户提交表单后,$name
属性将提交到服务器保存。
这就是字段在 Filament 中的基础工作原理。每个字段都分配到 Livewire 组件类公共属性,该属性是字段状态的存储位置。我们把该字段的名称称为字段的 "state path"。在字段视图中可以使用 $getStatePath()
函数访问字段的 state path:
<input wire:model="{{ $getStatePath() }}" />
<!-- Or -->
<div x-data="{ state: $wire.entangle('{{ $getStatePath() }}') }">
<input x-model="state" />
</div>
如果你的组件严重依赖第三方库,我们建议你使用 Filament 资源系统异步加载 Alpine.js 组件。这保证了 Alpine.js 组件只会在需要时加载,而不是每个页面都加载。要了解如何实现该功能,请查阅资源文档。
渲染字段包装器
Filament 中有一个"字段包装器(field wrapper)"组件,可以渲染字段标签,验证错误及字段周围的其他文本。你可以在视图中像这样渲染字段 wrapper:
<x-dynamic-component
:component="$getFieldWrapperView()"
:field="$field"
>
<!-- Field -->
</x-dynamic-component>
鼓励在适当的时候使用字段包装器组件,因为它将确保字段的设计与表单的其余部分一致。
访问 Eloquent 记录
使用 $getRecord()
函数,你可以在视图中访问 Eloquent 记录:
<div>
{{ $getRecord()->name }}
</div>
遵守状态绑定修饰符
当你将字段绑定到 state path 时,你可以使用 defer
修饰符去确保该状态只在用户提交表单时(或者下个 Livewire 请求发起时)发送到服务器。这是默认行为。
不过,你也可以在字段上使用 live()
来确保状态在用户和字段交互时立即发送给服务器。这就允许了许多文档高级部分中所介绍的高级用法。
Filament 提供了一个 $applyStateBindingModifiers()
函数,你可以使用它在视图中将所有的状态绑定修饰应用到 wire:model
或 $wire.entangle()
绑定:
<input {{ $applyStateBindingModifiers('wire:model') }}="{{ $getStatePath() }}" />
<!-- Or -->
<div x-data="{ state: $wire.{{ $applyStateBindingModifiers("entangle('{$getStatePath()}')") }} }">
<input x-model="state" />
</div>