Skip to content
全部文档

自定义条目

简介

你可以创建自己的自定义条目类与视图,在项目中复用,甚至作为插件发布给社区。

要创建自定义条目类与视图,可使用以下命令:

bash
php artisan make:filament-infolist-entry AudioPlayerEntry

这将创建如下组件类:

php
use Filament\Infolists\Components\Entry;

class AudioPlayerEntry extends Entry
{
    protected string $view = 'filament.infolists.components.audio-player-entry';
}

同时会在 resources/views/filament/infolists/components/audio-player-entry.blade.php 创建视图文件。

INFO

Filament infolist 条目不是 Livewire 组件。在 infolist 条目类上定义公共属性与方法,并不会使它们在 Blade 视图中可访问。

在 Blade 视图中访问条目状态

在 Blade 视图中,可使用 $getState() 函数访问条目的 状态

blade
<x-dynamic-component
    :component="$getEntryWrapperView()"
    :entry="$entry"
>
    {{ $getState() }}
</x-dynamic-component>

在 Blade 视图中访问另一个组件的状态

在 Blade 视图中,可使用 $get() 函数访问 schema 中另一个组件的状态:

blade
<x-dynamic-component
    :component="$getEntryWrapperView()"
    :entry="$entry"
>
    {{ $get('email') }}
</x-dynamic-component>

TIP

除非表单字段是 响应式的,否则字段值变化时 Blade 视图不会刷新,只有在下一次会向服务器发起请求的用户交互时才会刷新。若需要响应字段值的变化,应使用 live()

在 Blade 视图中访问 Eloquent 记录

在 Blade 视图中,可使用 $record 变量访问当前 Eloquent 记录:

blade
<x-dynamic-component
    :component="$getEntryWrapperView()"
    :entry="$entry"
>
    {{ $record->name }}
</x-dynamic-component>

在 Blade 视图中访问当前操作

在 Blade 视图中,可使用 $operation 变量访问当前操作,通常为 createeditview

blade
<x-dynamic-component
    :component="$getEntryWrapperView()"
    :entry="$entry"
>
    @if ($operation === 'create')
        This is a new conference.
    @else
        This is an existing conference.
    @endif
</x-dynamic-component>

在 Blade 视图中访问当前 Livewire 组件实例

在 Blade 视图中,可使用 $this 访问当前 Livewire 组件实例:

blade
@php
    use Filament\Resources\Users\RelationManagers\ConferencesRelationManager;
@endphp

<x-dynamic-component
    :component="$getEntryWrapperView()"
    :entry="$entry"
>
    @if ($this instanceof ConferencesRelationManager)
        You are editing conferences the of a user.
    @endif
</x-dynamic-component>

在 Blade 视图中访问当前条目实例

在 Blade 视图中,可使用 $entry 访问当前条目实例。可在该对象上调用公共方法,以访问变量中可能不可用的其他信息:

blade
<x-dynamic-component
    :component="$getEntryWrapperView()"
    :entry="$entry"
>
    @if ($entry->isLabelHidden())
        This is a new conference.
    @endif
</x-dynamic-component>

向自定义条目类添加配置方法

可向自定义条目类添加公共方法:接受配置值、存入受保护属性,再通过另一个公共方法返回:

php
use Filament\Infolists\Components\Entry;

class AudioPlayerEntry extends Entry
{
    protected string $view = 'filament.infolists.components.audio-player-entry';
    
    protected ?float $speed = null;

    public function speed(?float $speed): static
    {
        $this->speed = $speed;

        return $this;
    }

    public function getSpeed(): ?float
    {
        return $this->speed;
    }
}

现在,在自定义条目的 Blade 视图中,可使用 $getSpeed() 函数访问 speed:

blade
<x-dynamic-component
    :component="$getEntryWrapperView()"
    :entry="$entry"
>
    {{ $getSpeed() }}
</x-dynamic-component>

你在自定义条目类上定义的任何公共方法,都可在 Blade 视图中以这种方式作为变量函数访问。

要将配置值传给自定义条目类,可使用该公共方法:

php
use App\Filament\Infolists\Components\AudioPlayerEntry;

AudioPlayerEntry::make('recording')
    ->speed(0.5)

在自定义条目配置方法中允许工具注入

工具注入 是 Filament 的强大功能,允许用户使用可访问各种工具的函数来配置组件。可通过确保配置的参数类型与属性类型允许用户传入 Closure 来启用工具注入。在 getter 方法中,应将配置值传给 $this->evaluate() 方法:若用户传入函数则向其注入工具,若为静态值则直接返回:

php
use Closure;
use Filament\Infolists\Components\Entry;

class AudioPlayerEntry extends Entry
{
    protected string $view = 'filament.infolists.components.audio-player-entry';
    
    protected float | Closure | null $speed = null;

    public function speed(float | Closure | null $speed): static
    {
        $this->speed = $speed;

        return $this;
    }

    public function getSpeed(): ?float
    {
        return $this->evaluate($this->speed);
    }
}

现在,可向 speed() 方法传入静态值或函数,并将 任意工具 作为参数注入:

php
use App\Filament\Infolists\Components\AudioPlayerEntry;

AudioPlayerEntry::make('recording')
    ->speed(fn (Conference $record): float => $record->isGlobal() ? 1 : 0.5)

从 JavaScript 调用条目方法

有时需要从 Blade 视图中的 JavaScript 调用条目类上的方法。例如,你可能想异步获取数据或执行一些服务端计算。Filament 提供了使用 #[ExposedLivewireMethod] 属性将条目类上的方法暴露给 JavaScript 的方式。

暴露方法

要将方法暴露给 JavaScript,请在自定义条目类的公共方法上添加 #[ExposedLivewireMethod] 属性:

php
use Filament\Infolists\Components\Entry;
use Filament\Support\Components\Attributes\ExposedLivewireMethod;

class AudioPlayerEntry extends Entry
{
    protected string $view = 'filament.infolists.components.audio-player-entry';

    #[ExposedLivewireMethod]
    public function getWaveformData(): array
    {
        // Generate waveform data from the audio file...

        return $waveformData;
    }
}

INFO

只有标记了 #[ExposedLivewireMethod] 的方法才能从 JavaScript 调用。这是防止任意方法执行的安全措施。

从 JavaScript 调用方法

在 Blade 视图中,可用 $wire.callSchemaComponentMethod() 调用已暴露的方法。第一个参数是组件的 key(可通过 $getKey() 获取),第二个是方法名,第三个参数可传入实参:

blade
@php
    $key = $getKey();
@endphp

<x-dynamic-component
    :component="$getEntryWrapperView()"
    :entry="$entry"
>
    

        <template x-if="waveform">
            {{-- Render the waveform visualization --}}
        </template>
    

</x-dynamic-component>

防止重新渲染

默认情况下,调用已暴露方法会触发 Livewire 组件重新渲染。若方法无需更新 UI,可在 #[ExposedLivewireMethod] 旁加上 Livewire 的 #[Renderless] 属性以跳过重新渲染:

php
use Filament\Infolists\Components\Entry;
use Filament\Support\Components\Attributes\ExposedLivewireMethod;
use Livewire\Attributes\Renderless;

class AudioPlayerEntry extends Entry
{
    protected string $view = 'filament.infolists.components.audio-player-entry';

    #[ExposedLivewireMethod]
    #[Renderless]
    public function getWaveformData(): array
    {
        // ...
    }
}