资源
单体资源
概述
资源并非在 Filament 面板中与 Eloquent 记录交互的唯一方式。尽管资源可以解决你的许多需求,但资源的 “index”页面包含一个表,其中包含该资源中的记录列表。
有时不需要一个表来列出资源中的记录。用户只与一条记录交互。如果用户访问页面时该记录尚不存在,则会在用户首次提交表单以保存该记录时创建该记录。如果该记录已存在,则会在页面首次加载时将其加载到表单中,并在提交表单时更新。
例如,CMS 可能有一个 Page
Eloquent 模型和一个 PageResource
,但您可能还希望在 PageResource
之外创建一个单独的页面来编辑网站的“主页”。这允许用户直接编辑主页,而无需导航到 PageResource
并在表中查找主页记录。
其他示例包括“设置”页面或当前登录用户的“个人资料”页面。不过,对于这些用例,我们建议你使用 Filament 的 Spatie 设置插件 和 个人资料 功能,他们需要的代码较少。
创建单体资源
虽然 Filament 中没有专门的“单体资源”功能,但它是一项用户呼声很高的功能,可以通过使用自定义页面和 、表单轻松实现。本指南将讲解如何操作。
首先,创建一个自定义页面:
php artisan make:filament-page ManageHomepage
该命令将创建两个文件 - 一个资源目录的 /Filament/Pages
中的页面类,以及资源视图目录的 /filament/pages
目录中的 Blade 视图。
页面类应包含以下元素:
$data
属性,用于保存表单的当前状态。mount()
方法,用于从数据库加载当前记录并用其数据填充表单。如果记录不存在,则null
将被传递给表单的fill()
方法,该方法将为表单字段分配默认值。form()
方法,用于定义表单 Schema。表单包含components()
方法中的字段。record()
方法用于指定表单应从哪个记录加载关联数据。statePath()
方法用于指定应存储表单状态的属性($data
)的名称。save()
方法,用于将表单数据保存到数据库。getState()
方法运行表单验证并返回有效的表单数据。此方法应检查记录是否已存在,如果不存在,则创建新记录。模型的wasRecentlyCreated
属性可用于判断记录是否刚刚创建,如果是,则所有关联也应保存。系统会向用户发送通知,确认记录已保存。getRecord()
方法虽然并非必需,但最好添加。此方法将返回表单正在编辑的 Eloquent 记录。它可以与其他方法一起使用,以避免代码重复。
namespace App\Filament\Pages;
use App\Models\WebsitePage;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Schemas\Schema;
/**
* @property-read Schema $form
*/
class ManageHomepage extends Page
{
/**
* @var array<string, mixed> | null
*/
public ?array $data = [];
public function mount(): void
{
$this->form->fill($this->getRecord()?->attributesToArray());
}
public function form(Schema $schema): Schema
{
return $schema
->components([
TextInput::make('title')
->required()
->maxLength(255),
RichEditor::make('content'),
// ...
])
->record($this->getRecord())
->statePath('data');
}
public function save(): void
{
$data = $this->form->getState();
$record = $this->getRecord();
if (! $record) {
$record = new WebsitePage();
$record->is_homepage = true;
}
$record->fill($data);
$record->save();
if ($record->wasRecentlyCreated) {
$this->form->record($record)->saveRelationships();
}
Notification::make()
->success()
->title('Saved')
->send();
}
public function getRecord(): ?WebsitePage
{
return WebsitePage::query()
->where('is_homepage', true)
->first();
}
}
其页面 Blade 视图应该渲染表单和保存按钮。wire:submit
指令用来在表单提交时调用 save()
命令:
<x-filament::page>
<form wire:submit="save">
{{ $this->form }}
<div>
<x-filament::button type="submit">
Save
</x-filament::button>
</div>
</form>
</x-filament::page>
Edit on GitHubStill need help? Join our Discord community or open a GitHub discussion