1.5. 资源 - Creating records
面板生成器 - 资源 - 创建记录
保存前自定义数据
有时,你可能希望在表单数据最终保存到数据库之前对其进行修改。为此,你可以在创建页面类上定义一个 mutateFormDataBeforeCreate()
方法,该方法接受 $data
数组,并返回修改后的版本:
protected function mutateFormDataBeforeCreate(array $data): array
{
$data['user_id'] = auth()->id();
return $data;
}
另外,如果你想在模态动作中创建记录,请查看动作文档。
自定义创建过程
你可以使用创建页面类上的 handleRecordCreation()
方法调整创建记录的方式:
use Illuminate\Database\Eloquent\Model;
protected function handleRecordCreation(array $data): Model
{
return static::getModel()::create($data);
}
另外,如果你要在模态动作中创建记录,请查看动作文档。
自定义重定向
默认情况下,保存表单后,用户将被重定向到资源的编辑页面,或查看页面(如果存在)。
保存表单时,可以通过重载创建页面类上的 getRedirectUrl()
方法来设置自定义重定向。
例如,表单可以重定向回 List page:
protected function getRedirectUrl(): string
{
return $this->getResource()::getUrl('index');
}
如果你希望重定向到前一页,可选择索引页:
protected function getRedirectUrl(): string
{
return $this->previousUrl ?? $this->getResource()::getUrl('index');
}
自定义保存通知
成功创建记录后,系统会向用户发送通知,说明其操作成功。
要自定义此通知的标题,请在创建页面类上定义getCreatedNotificationTitle()
方法:
protected function getCreatedNotificationTitle(): ?string
{
return 'User registered';
}
另外,如果你在模态动作中创建记录,请查看动作文档。
你可以通过覆盖创建页面类上的 getCreatedNotification()
方法来定制整个通知:
use Filament\Notifications\Notification;
protected function getCreatedNotification(): ?Notification
{
return Notification::make()
->success()
->title('User registered')
->body('The user has been created successfully.');
}
要完全禁用通知,可通过创建页面类上的 getCreatedNotification()
方法返回 null
:
use Filament\Notifications\Notification;
protected function getCreatedNotification(): ?Notification
{
return null;
}
生命周期钩子
钩子可用于在页面生命周期的不同阶段执行代码,例如在保存表单之前。要设置钩子,请在创建页面类上创建一个保护方法,并写上钩子的名称:
protected function beforeCreate(): void
{
// ...
}
在本例中,beforeCreate()
方法中的代码将在表单中的数据保存到数据库之前调用。
创建页面有几个可用的钩子:
use Filament\Resources\Pages\CreateRecord;
class CreateUser extends CreateRecord
{
// ...
protected function beforeFill(): void
{
// 在表单字段填充默认值之前运行。
}
protected function afterFill(): void
{
// 在表单字段填入默认值后运行。
}
protected function beforeValidate(): void
{
// 在提交表单时验证表单字段之前运行。
}
protected function afterValidate(): void
{
// 在提交表单时,表单字段通过验证后运行。
}
protected function beforeCreate(): void
{
//在表单字段保存到数据库之前运行。
}
protected function afterCreate(): void
{
//在表单字段保存到数据库后运行。
}
}
另外,如果你要在模态操作中创建记录,请查看操作文档。
停止创建过程
你可以随时在生命周期钩子或突变方法中调用 $this->halt()
,这将停止整个创建过程:
use Filament\Notifications\Actions\Action;
use Filament\Notifications\Notification;
protected function beforeCreate(): void
{
if (! $this->getRecord()->team->subscribed()) {
Notification::make()
->warning()
->title('You don\'t have an active subscription!')
->body('Choose a plan to continue.')
->persistent()
->actions([
Action::make('subscribe')
->button()
->url(route('subscribe'), shouldOpenInNewTab: true),
])
->send();
$this->halt();
}
}
另外,如果你要在模态操作中创建记录,请查看操作文档。
授权
在授权方面,Filament 将遵守在应用程序中注册的任何 模型策略。
如果模型策略的 create()
方法返回 true
,用户就可以访问创建页面。
使用向导
你可以轻松地将创建过程转换为多步骤向导。
在页面类中,添加相应的 HasWizard
特质:
use App\Filament\Resources\CategoryResource;
use Filament\Resources\Pages\CreateRecord;
class CreateCategory extends CreateRecord
{
use CreateRecord\Concerns\HasWizard;
protected static string $resource = CategoryResource::class;
protected function getSteps(): array
{
return [
// ...
];
}
}
在getSteps()
数组中,返回你的向导步骤:
use Filament\Forms\Components\MarkdownEditor;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Components\Wizard\Step;
protected function getSteps(): array
{
return [
Step::make('Name')
->description('Give the category a clear and unique name')
->schema([
TextInput::make('name')
->required()
->live()
->afterStateUpdated(fn ($state, callable $set) => $set('slug', Str::slug($state))),
TextInput::make('slug')
->disabled()
->required()
->unique(Category::class, 'slug', fn ($record) => $record),
]),
Step::make('Description')
->description('Add some extra details')
->schema([
MarkdownEditor::make('description')
->columnSpan('full'),
]),
Step::make('Visibility')
->description('Control who can view it')
->schema([
Toggle::make('is_visible')
->label('Visible to customers.')
->default(true),
]),
];
}
另外,如果你要在模态动作中创建记录,请查看操作文档。
现在,创建一条新记录,看看向导的运行情况!编辑仍将使用资源类中定义的表单。
如果想允许自由导航,使所有步骤都可跳过,可覆盖 hasSkippableSteps()
方法:
public function hasSkippableSteps(): bool
{
return true;
}
在资源表单和向导之间共享字段
如果想减少资源表单和向导步骤之间的重复,最好为字段提取公共静态资源函数,这样就可以轻松地从资源或向导中获取字段实例:
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
class CategoryResource extends Resource
{
public static function form(Form $form): Form
{
return $form
->schema([
static::getNameFormField(),
static::getSlugFormField(),
// ...
]);
}
public static function getNameFormField(): Forms\Components\TextInput
{
return TextInput::make('name')
->required()
->live()
->afterStateUpdated(fn ($state, callable $set) => $set('slug', Str::slug($state)));
}
public static function getSlugFormField(): Forms\Components\TextInput
{
return TextInput::make('slug')
->disabled()
->required()
->unique(Category::class, 'slug', fn ($record) => $record);
}
}
use App\Filament\Resources\CategoryResource;
use Filament\Resources\Pages\CreateRecord;
class CreateCategory extends CreateRecord
{
use CreateRecord\Concerns\HasWizard;
protected static string $resource = CategoryResource::class;
protected function getSteps(): array
{
return [
Step::make('Name')
->description('Give the category a clear and unique name')
->schema([
CategoryResource::getNameFormField(),
CategoryResource::getSlugFormField(),
]),
// ...
];
}
}
自定义视图
要进一步自定义,可以将页面类上的静态 $view
属性覆盖到应用程序中的自定义视图:
protected static string $view = 'filament.resources.users.pages.create-user';
假设你已在 resources/views/filament/resources/users/pages/create-user.blade.php
中创建了一个视图。
下面是该视图可能包含内容的一个基本示例:
<x-filament-panels::page>
<x-filament-panels::form wire:submit="create">
{{ $this->form }}
<x-filament-panels::form.actions
:actions="$this->getCachedFormActions()"
:full-width="$this->hasFullWidthFormActions()"
/>
</x-filament-panels::form>
</x-filament-panels::page>
要查看默认视图包含的所有内容,可以检查项目中的 vendor/filament/filament/resources/views/resources/pages/create-record.blade.php
文件。
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
推荐文章: