NOTE

You are currently viewing the documentation for Filament 4.x, which is a previous version of Filament.

Looking for the current stable version? Visit the 5.x documentation.

资源

代码质量 Tips

使用 Schema 和表格类

由于许多 Filament 方法仅在一个方法中定义应用的 UI 和功能,因此很容易产生庞大的方法和文件。即使你的代码风格简洁一致,这些方法和文件也可能难以阅读。

Filament 尝试通过在生成资源时提供专用的 Schema 和表格类来缓解部分问题。这些类都有一个 configure() 方法,该方法接受 $schema$table 作为参数。然后,你可以从任何想要定义 Schema 或表格的地方调用该 configure() 方法。

例如,如果你有以下 app/Filament/Resources/Customers/Schemas/CustomerForm.php 文件:

namespace App\Filament\Resources\Customers\Schemas;

use Filament\Forms\Components\TextInput;
use Filament\Schemas\Schema;

class CustomerForm
{
    public static function configure(Schema $schema): Schema
    {
        return $schema
            ->components([
                TextInput::make('name'),
                // ...
            ]);
    }
}

你可以在资源的 form() 方法中使用它:

use App\Filament\Resources\Customers\Schemas\CustomerForm;
use Filament\Schemas\Schema;

public static function form(Schema $schema): Schema
{
    return CustomerForm::configure($schema);
}

你页可以对 table() 执行相同的操作:

use App\Filament\Resources\Customers\Schemas\CustomersTable;
use Filament\Tables\Table;

public static function table(Table $table): Table
{
    return CustomersTable::configure($table);
}

或者 infolist()

use App\Filament\Resources\Customers\Schemas\CustomerInfolist;
use Filament\Schemas\Schema;

public static function infolist(Schema $schema): Schema
{
    return CustomerInfolist::configure($schema);
}

这些模式和表类默认没有父类或接口。如果 Filament 强制 configure() 方法使用方法签名,你将无法将自己的配置变量传递给该方法。如果你希望在多个地方重用同一个类,但需要进行一些细微的调整,那么这种方法就非常有用。

使用组件类

即使你使用 Schema 和表类将架构和表定义保存在各自的文件中,最终仍然可能需要一个非常长的 configure() 方法。如果你在 Schema 或表格中使用了大量组件,或者这些组件需要进行大量配置,则尤其如此。

你可以通过为每个组件创建专用类来缓解这种情况。例如,如果你有一个需要大量配置的 TextInput 组件,你可以为其创建一个专用类:

namespace App\Filament\Resources\Customers\Schemas\Components;

use Filament\Forms\Components\TextInput;

class CustomerNameInput
{
    public static function make(): TextInput
    {
        return TextInput::make('name')
            ->label('Full name')
            ->required()
            ->maxLength(255)
            ->placeholder('Enter your full name')
            ->belowContent('This is the name that will be displayed on your profile.');
    }
}

你可以在 Schma 或者表格中使用这个类:

use App\Filament\Resources\Customers\Schemas\Components\CustomerNameInput;
use Filament\Schemas\Schema;

public static function configure(Schema $schema): Schema
{
    return $schema
        ->components([
            CustomerNameInput::make(),
            // ...
        ]);
}

你可以使用多种不同类型的组件来实现这一点。对于这些组件的命名方式或存储位置,并没有强制的规则。不过,这里有一些建议:

  • Schema 组件:这些组件可以位于资源的 Schemas/Components 目录中。它们可以以其所包装的组件命名,例如 CustomerNameInputCustomerCountrySelect
  • 表格列:这些组件可以位于资源的 Tables/Columns 目录中。它们可以以列字段名后跟 Column 命名,例如 CustomerNameColumnCustomerCountryColumn
  • 表格过滤器:这些组件可以位于资源的 Tables/Filters 目录中。它们可以以过滤器后跟 Filter 命名,例如 CustomerCountryFilterCustomerStatusFilter
  • Action:这些组件可以位于资源的 Actions 目录中。它们可以以操作后跟 ActionBulkAction 命名,例如 EmailCustomerActionUpdateCustomerCountryBulkAction

作为进一步的例子,以下是 EmailCustomerAction 类:

namespace App\Filament\Resources\Customers\Actions;

use App\Models\Customer;
use Filament\Actions\Action;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Support\Icons\Heroicon;

class EmailCustomerAction
{
    public static function make(): Action
    {
        return Action::make('email')
            ->label('Send email')
            ->icon(Heroicon::Envelope)
            ->schema([
                TextInput::make('subject')
                    ->required()
                    ->maxLength(255),
                Textarea::make('body')
                    ->autosize()
                    ->required(),
            ])
            ->action(function (Customer $customer, array $data) {
                // ...
            });
    }
}

你可以在页面的 getHeaderActions() 中使用它:

use App\Filament\Resources\Customers\Actions\EmailCustomerAction;

protected function getHeaderActions(): array
{
    return [
        EmailCustomerAction::make(),
    ];
}

或者可以在表格行中使用:

use App\Filament\Resources\Customers\Actions\EmailCustomerAction;
use Filament\Tables\Table;

public static function configure(Table $table): Table
{
    return $table
        ->columns([
            // ...
        ])
        ->recordActions([
            EmailCustomerAction::make(),
        ]);
}
Edit on GitHub

Still need help? Join our Discord community or open a GitHub discussion

Previous
自定义资源页