如何在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
相关产品推荐
相关产品推荐

