Filament 文档 提供了一个很好的复制粘贴解决方案,用于从标题生成 Slug。
此示例将标题字段设置为 Livewire Live 字段,然后,当您输入字符时,它会生成一个 Slug 并将其设置为另一个表单字段。
use Filament\Forms\Components\TextInput;use Filament\Forms\Set;use Illuminate\Support\Str; TextInput::make('title') ->live() ->afterStateUpdated(fn (Set $set, ?string $state) => $set('slug', Str::slug($state))) TextInput::make('slug')
这对于大多数情况都很好用,但我希望更进一步,只有在它是新条目或尚未发布时才动态更改 Slug。否则,如果 Slug 发生变化,它会导致 404,因为旧的 Slug 不存在。
为了解决这个问题,这里有一个更新的版本,它只在它是新记录或尚未发布时更新
TextInput::make('title') ->live() ->afterStateUpdated(function (Get $get, Set $set, ?string $operation, ?string $old, ?string $state, ?Model $record) { if ($operation == 'edit' && $record->isPublished()) { return; } if (($get('slug') ?? '') !== Str::slug($old)) { return; } $set('slug', Str::slug($state));})
为了解释代码,Filament 中的 afterStateUpdated
允许您注入操作(创建或编辑)和模型,然后您可以使用它们来确定是否应该更新 Slug 或者保持不变。这就是 if 语句的作用
if ($operation == 'edit' && $record->isPublished())
这意味着如果我们在编辑页面上,并且模型已发布,则跳过动态设置 Slug。
您可能还想在记录已发布时禁用 Slug 字段,这很容易实现
TextInput::make('slug') ->required() ->maxLength(255) ->unique(Article::class, 'slug', fn ($record) => $record) ->disabled(fn (?string $operation, ?Model $record) => $operation == 'edit' && $record->isPublished())
感谢 Alex Six 帮助我设置并完成这项工作。