信息列表
Custom entries
简介
你可以创建你自己的自定义条目(Entry)类及视图,它可以在整个应用中进行重用,甚至可以将其作为插件发布到社区。
要创建自定义条目(Entry)类及视图,请使用如下命令:
php artisan make:filament-infolist-entry AudioPlayerEntry
该命令将创建以下组件类:
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。
NOTE
Filament 信息列表条目不是 Livewire 组件。在条目类中定义公共属性和方法不会使之在 Blade 视图中可访问到。
在 Blade 视图中访问条目状态
在 Blade 视图中,你可以使用 $getState() 函数访问条目的状态值:
<x-dynamic-component
:component="$getEntryWrapperView()"
:entry="$entry"
>
{{ $getState() }}
</x-dynamic-component>
在 Blade 视图中访问其他组件的状态
在 Blade 视图中,你可以使用 $get() 函数访问 Schema 中其他组件的状态值:
<x-dynamic-component
:component="$getEntryWrapperView()"
:entry="$entry"
>
{{ $get('email') }}
</x-dynamic-component>
TIP
除非表单字段是响应式的,否则当字段值改变时,Blade 视图不会刷新,只有当下一次用户交互向服务器发起请求时才会刷新。如果你需要在字段值改变时响应,请使用 live()。
在 Blade 视图中访问 Eloquent 记录
在 Blade 视图中,你可以使用 $record 变量访问当前 Element 记录:
<x-dynamic-component
:component="$getEntryWrapperView()"
:entry="$entry"
>
{{ $record->name }}
</x-dynamic-component>
在 Blade 视图中访问当前操作
在 Blade 视图中,你可以使用 $operation 变量访问当前操作(通常为 create、edit 或者 view):
<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 组件实例:
@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 视图中访问当前 Entry 实例
在 Blade 视图中,你可以使用 $entry 访问当前 Entry 组件实例。你可以在该对象上调用公用方法,访问其他以变量形式访问不到的信息:
<x-dynamic-component
:component="$getEntryWrapperView()"
:entry="$entry"
>
@if ($entry->isLabelHidden())
This is a new conference.
@endif
</x-dynamic-component>
添加配置方法到自定义 Entry 类中
你可以添加 public 方法到自定义 Entry 类中,使之接受一个配置值,然后将该值保存到 protected 属性中,并在另一个 public 函数中返回该值:
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;
}
}
现在,在自定义 Entry 的 Blade 视图中,你可以使用 $getSpeed() 函数访问该 speed:
<x-dynamic-component
:component="$getEntryWrapperView()"
:entry="$entry"
>
{{ $getSpeed() }}
</x-dynamic-component>
任何你在自定义 Entry 类中定义的 public 方法,可以在 Blade 视图中以这样的方式作为变量函数访问。
要传递配置值到自定义 Entry 类中,你可以使用 public 方法:
use App\Filament\Infolists\Components\AudioPlayerEntry;
AudioPlayerEntry::make('recording')
->speed(0.5)
在自定义 Entry 配置方法中允许 utility 注入
Utility 注入是 Filament 的一个强大的功能,它允许用户使用可以访问各种 utility 的函数配置组件。你可以通过确保配置的参数类型和属性类型允许用户传递 Closure 闭包来允许 utility 注入。在 getter 方法中,你应该传入配置值到 $this-?evaluate() 方法中,如果用户传入函数,该方法会将 utility 注入到用户函数中,或者,如果传入的是静态值将返回该值:
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() 方法中,并注入 utiltiy作为参数:
use App\Filament\Infolists\Components\AudioPlayerEntry;
AudioPlayerEntry::make('recording')
->speed(fn (Conference $record): float => $record->isGlobal() ? 1 : 0.5)
从 JavaScript 调用 Entry 方法
有时,你需要在 Blade 视图中通过 JavaScript 调用 Entry 类中的方法。例如,你可能希望异步获取数据或执行某些服务端计算。Filament 提供了一种机制,允许你使用 #[ExposedLivewireMethod] 属性将 Entry 类中的方法暴露给 JavaScript。
暴露方法
若要将方法暴露给 JavaScript,请在自定义 Entry 类的公共方法上添加 #[ExposedLivewireMethod] 属性:
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;
}
}
NOTE
Only methods marked with #[ExposedLivewireMethod] can be called from JavaScript. This is a security measure to prevent arbitrary method execution.
从 JavaScript 调用方法
在 Blade 视图中,你可以使用 $wire.callSchemaComponentMethod() 调用暴露的方法。第一个参数是组件的键(可通过 $getKey() 获得),第二个参数是方法名称。你可以将参数作为第三个参数传递:
@php
$key = $getKey();
@endphp
<x-dynamic-component
:component="$getEntryWrapperView()"
:entry="$entry"
>
<div
x-data="{
waveform: null,
async loadWaveform() {
this.waveform = await $wire.callSchemaComponentMethod(
@js($key),
'getWaveformData',
)
},
}"
x-init="loadWaveform"
>
<template x-if="waveform">
{{-- Render the waveform visualization --}}
</template>
</div>
</x-dynamic-component>
避免重新渲染
默认情况下,调用公开方法会触发 Livewire 组件的重新渲染。如果你的方法不需要更新 UI,可以在 #[ExposedLivewireMethod] 旁边添加 Livewire 的 #[Renderless] 属性,从而跳过重新渲染:
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
{
// ...
}
}
Edit on GitHubStill need help? Join our Discord community or open a GitHub discussion