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 文件。

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/laravel-filamen...

译文地址:https://learnku.com/docs/laravel-filamen...

上一篇 下一篇
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
贡献者:3
讨论数量: 0
发起讨论 查看所有版本


暂无话题~