Skip to content
全部文档

查看记录

资源查看页面资源查看页面

创建带查看页的资源

要创建带查看页的新资源,可使用 --view 标志:

bash
php artisan make:filament-resource User --view

用 infolist 替代禁用表单

默认情况下,查看页会以禁用表单展示记录数据。若更希望用「infolist」展示,可在资源类上定义 infolist() 方法:

php
use Filament\Infolists;
use Filament\Schemas\Schema;

public static function infolist(Schema $schema): Schema
{
    return $schema
        ->components([
            Infolists\Components\TextEntry::make('name'),
            Infolists\Components\TextEntry::make('email'),
            Infolists\Components\TextEntry::make('notes')
                ->columnSpanFull(),
        ]);
}

components() 方法用于定义 infolist 结构,是按显示顺序排列的 条目布局组件 数组。

请参阅 Infolists 文档中的 指南,了解如何用 Filament 构建 infolist。

为现有资源添加查看页

若要为现有资源添加查看页,请在资源的 Pages 目录中创建新页面:

bash
php artisan make:filament-page ViewUser --resource=UserResource --type=ViewRecord

你必须在资源的 getPages() 方法中注册该新页面:

php
public static function getPages(): array
{
    return [
        'index' => Pages\ListUsers::route('/'),
        'create' => Pages\CreateUser::route('/create'),
        'view' => Pages\ViewUser::route('/{record}'),
        'edit' => Pages\EditUser::route('/{record}/edit'),
    ];
}

在模态中查看记录

若资源较简单,你可能希望在模态中查看记录,而不是在 查看页。此时只需 删除查看页

若资源中没有 ViewAction,可将其加入 $table->recordActions() 数组:

php
use Filament\Actions\ViewAction;
use Filament\Tables\Table;

public static function table(Table $table): Table
{
    return $table
        ->columns([
            // ...
        ])
        ->recordActions([
            ViewAction::make(),
            // ...
        ]);
}

填充表单前自定义数据

你可能希望在数据填入表单前修改记录数据。可在查看页类上定义 mutateFormDataBeforeFill(),修改 $data 数组并返回修改后的版本,再填入表单:

php
protected function mutateFormDataBeforeFill(array $data): array
{
    $data['user_id'] = auth()->id();

    return $data;
}

或者,若在模态操作中查看记录,请参阅 操作文档

生命周期钩子

钩子可在页面生命周期的多个节点执行代码,例如在表单填充前。要设置钩子,在查看页类上创建与钩子同名的 protected 方法:

php
use Filament\Resources\Pages\ViewRecord;

class ViewUser extends ViewRecord
{
    // ...

    protected function beforeFill(): void
    {
        // Runs before the disabled form fields are populated from the database. Not run on pages using an infolist.
    }

    protected function afterFill(): void
    {
        // Runs after the disabled form fields are populated from the database. Not run on pages using an infolist.
    }
}

在 trait 中定义生命周期钩子

要在 trait 中定义生命周期钩子,请在钩子名后加上 trait 名称。这遵循 Eloquent 的 boot{TraitName}() 与 Livewire 的 mount{TraitName}() 约定,使可复用 trait 能接入页面生命周期,又不会与页面自身定义的钩子冲突:

php
use Filament\Resources\Pages\ViewRecord;

trait LoadsAuditData
{
    protected function afterFillLoadsAuditData(): void
    {
        // Runs after the form fields are populated from the database, in
        // addition to the hook on the page.
    }
}

class ViewUser extends ViewRecord
{
    use LoadsAuditData;

    protected function afterFill(): void
    {
        // Both lifecycle hooks are called.
    }
}

页面自身的钩子先调用,随后是各个 trait 钩子。其他 trait 所使用的 trait 中的钩子也会被调用。Trait 钩子会自动调用,因此不应再从页面自身的钩子中调用它们。

授权

对于授权,Filament 会遵循应用中已注册的任意 模型策略

若模型策略的 view() 方法返回 true,用户即可访问查看页。

创建另一个查看页

单个查看页可能不足以承载大量信息。你可以为资源创建任意多个查看页。若使用 资源子导航,在不同查看页之间切换会特别方便。

要创建查看页,应使用 make:filament-page 命令:

bash
php artisan make:filament-page ViewCustomerContact --resource=CustomerResource --type=ViewRecord

你必须在资源的 getPages() 方法中注册该新页面:

php
public static function getPages(): array
{
    return [
        'index' => Pages\ListCustomers::route('/'),
        'create' => Pages\CreateCustomer::route('/create'),
        'view' => Pages\ViewCustomer::route('/{record}'),
        'view-contact' => Pages\ViewCustomerContact::route('/{record}/contact'),
        'edit' => Pages\EditCustomer::route('/{record}/edit'),
    ];
}

现在可为该页面定义 infolist()form(),其中可包含主查看页上没有的其他组件:

php
use Filament\Schemas\Schema;

public function infolist(Schema $schema): Schema
{
    return $schema
        ->components([
            // ...
        ]);
}

为特定查看页自定义关联管理器

可通过定义 getAllRelationManagers() 方法,指定查看页上应出现哪些关联管理器:

php
protected function getAllRelationManagers(): array
{
    return [
        CustomerAddressesRelationManager::class,
        CustomerContactsRelationManager::class,
    ];
}

当你有 多个查看页 且各页需要不同关联管理器时,这很有用:

php
// ViewCustomer.php
protected function getAllRelationManagers(): array
{
    return [
        RelationManagers\OrdersRelationManager::class,
        RelationManagers\SubscriptionsRelationManager::class,
    ];
}

// ViewCustomerContact.php 
protected function getAllRelationManagers(): array
{
    return [
        RelationManagers\ContactsRelationManager::class,
        RelationManagers\AddressesRelationManager::class,
    ];
}

若未定义 getAllRelationManagers(),将使用资源中定义的关联管理器。

将查看页加入资源子导航

若使用 资源子导航,可在资源的 getRecordSubNavigation() 中照常注册该页面:

php
use App\Filament\Resources\Customers\Pages;
use Filament\Resources\Pages\Page;

public static function getRecordSubNavigation(Page $page): array
{
    return $page->generateNavigationItems([
        // ...
        Pages\ViewCustomerContact::class,
    ]);
}

自定义页面内容

Filament 中每个页面都有自己的 schema,定义整体结构与内容。可通过定义 content() 方法覆盖页面 schema。查看页的 content() 默认包含以下组件:

php
use Filament\Schemas\Schema;

public function content(Schema $schema): Schema
{
    return $schema
        ->components([
            $this->hasInfolist() // This method returns `true` if the page has an infolist defined
                ? $this->getInfolistContentComponent() // This method returns a component to display the infolist that is defined in this resource
                : $this->getFormContentComponent(), // This method returns a component to display the form that is defined in this resource
            $this->getRelationManagersContentComponent(), // This method returns a component to display the relation managers that are defined in this resource
        ]);
}

components() 数组中可插入任意 schema 组件。可通过调整数组顺序重排组件,或移除不需要的组件。

使用自定义 Blade 视图

若需进一步自定义,可将页面类上的静态 $view 属性覆盖为应用中的自定义视图:

php
protected string $view = 'filament.resources.users.pages.view-user';

这假定你已在 resources/views/filament/resources/users/pages/view-user.blade.php 创建了视图:

blade
<x-filament-panels::page>
    {{-- `$this->getRecord()` will return the current Eloquent record for this page --}}
    
    {{ $this->content }} {{-- This will render the content of the page defined in the `content()` method, which can be removed if you want to start from scratch --}}
</x-filament-panels::page>