You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel Nova详情页展示Repeater字段的JSON数据

如何在Filament详情页展示Repeater字段存储的JSON数据

我在Filament资源中使用Repeater字段,编辑时功能正常,但不知道怎么在详情页展示它保存的JSON数据。我尝试用KeyValue字段,但两者的JSON格式不匹配:

Repeater存储的JSON格式是数组结构:

[
    {
        "type": "location-contact",
        "fields": {
            "name": "mike",
            "email": "mike@mike.com"
        }
    },
    {
        "type": "location-contact",
        "fields": {
            "name": "john",
            "email": "john@john.com"
        }
    },
    {
        "type": "location-contact",
        "fields": {
            "name": "Mary",
            "email": "mary@mary.com"
        }
    }
]

而KeyValue字段期望的是单个对象结构:

{
    "name": "mike",
    "email": "mike@mike.com"
}

现有两种尝试的代码,但不确定是否正确:

// 尝试用Repeater直接展示
Repeater::make('Location Contacts', 'location_contacts')
          ->repeatables([
              LocationContact::make(),
            ])->asJson(),
// 尝试用KeyValue展示
KeyValue::make('Location Contacts', 'location_contacts'), 

方案一:直接用Repeater字段在详情页展示

Repeater字段本身支持在详情页渲染,不需要额外转换格式。只要在资源的detail()方法中添加该Repeater字段即可,Filament会自动解析存储的JSON数组,按照你定义的LocationContact组件结构渲染每个条目:

public static function detail(Detail $page): Detail
{
    return $page
        ->schema([
            // 其他详情字段
            Repeater::make('location_contacts')
                ->repeatables([
                    LocationContact::make(),
                ]),
        ]);
}

不需要添加->asJson(),这个方法用于指定存储格式,详情页展示时Filament会自动处理已存储的JSON数据,还原成对应的表单组件结构展示。

方案二:用KeyValue字段处理数据后展示

如果你确实想用KeyValue字段展示每个联系人的信息,需要先提取Repeater存储的JSON中每个条目的fields数据,可通过getStateUsing()方法转换数据结构:

方式1:合并展示所有联系人信息

KeyValue::make('Location Contacts')
    ->getStateUsing(function ($record) {
        $contacts = json_decode($record->location_contacts, true);
        $merged = [];
        foreach ($contacts as $index => $contact) {
            $merged["联系人 " . ($index + 1) . " 姓名"] = $contact['fields']['name'];
            $merged["联系人 " . ($index + 1) . " 邮箱"] = $contact['fields']['email'];
        }
        return $merged;
    });

方式2:按联系人独立展示键值对

如果想保留每个联系人的独立结构,可以在Repeater里嵌套KeyValue字段:

Repeater::make('location_contacts')
    ->schema([
        KeyValue::make('联系人信息')
            ->getStateUsing(function ($state) {
                return $state['fields'];
            }),
    ]);

这样每个联系人的fields对象会被KeyValue字段解析成键值对形式展示,同时保留Repeater的条目分隔结构。


内容的提问来源于stack exchange,提问作者mcornille

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 14:18:22