测试版说明
此字段当前处于测试版。API 虽然稳定,但在测试期内可能会发生变化。
Repeater 字段允许你创建和编辑可重复的结构化数据,并将该数据存储在 JSON 列或 HasMany 关联中:
<?php
namespace App\Nova;
use App\Nova\Repeater\LineItem;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Repeater;
use Laravel\Nova\Http\Requests\NovaRequest;
class Invoice extends Resource
{
/**
* 获取资源显示的字段。
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request)
{
return [
ID::make(),
Repeater::make('Line Items')
->repeatables([
LineItem::make(),
]),
];
}
}定义 Repeater 字段后,你的资源将拥有一个优雅的界面,用于添加和编辑字段中的可重复项:

一个 Repeatable 对象代表一个 Repeater 字段的可重复数据。它定义了用于可重复项的字段集。当 Repeater 使用 HasMany 预设时,它还可选择定义一个 Eloquent Model 类。
Repeater 中继器字段并不局限于单一的可重复类型。它还支持多种「可重复」类型,这些类型可能包含各自独特的字段集和模型。这些可重复内容可用于创建编辑灵活内容区域的界面,类似于内容管理系统提供的界面。
要生成新的中继器 Repeatable,请调用 nova:repeatable Artisan 命令:
php artisan nova:repeatable LineItem调用上述命令后,Nova 会生成一个新文件 app/Nova/Repeater/LineItem.php。该文件包含一个 fields 方法,你可以在其中列出任何 Nova 支持的字段。例如,下面我们将定义一个 Repeatable 字段,代表发票的行项目:
<?php
namespace App\Nova\Repeater;
use Laravel\Nova\Http\Requests\NovaRequest;
use Laravel\Nova\Fields\Currency;
use Laravel\Nova\Fields\Number;
use Laravel\Nova\Fields\Repeater\Repeatable;
use Laravel\Nova\Fields\Textarea;
class LineItem extends Repeatable
{
/**
* 获取可重复显示的字段。
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request)
{
return [
Number::make('Quantity')->rules('required', 'numeric'),
Textarea::make('Description')->rules('required', 'max:255'),
Currency::make('Price')->rules('required', 'numeric'),
];
}
}你可以在定义可重复数据时调用 confirmRemoval 方法,指示 Nova 在删除可重复数据前显示一个确认界面:
Repeater::make('Attachments')->repeatables([
\App\Nova\Repeater\File::make()->confirmRemoval(),
\App\Nova\Repeater\Note::make(),
\App\Nova\Repeater\Video::make()->confirmRemoval(),
]),Repeater 中继器字段包括两个开箱即用的存储「预设」:Json 和 HasMany。每个预设都定义了从数据库中存储和检索可重复数据的方式。
例如,Invoice 资源可以使用 Repeater 字段来编辑发票的行项目。使用 Laravel\Nova\Fields\Repeater\JSON 预设,这些行项目将存储在 line_items JSON 列中。但是,使用 HasMany 预设时,行项目将存储在一个单独的「line_items」数据库表中,每个数据库列都有相应的字段。
JSON 预设可将重复项存储在数据库中的 JSON 列中。例如,发票的明细项目可存储在 line_items 列中。当使用 JSON 预设保存带有 Repeater 字段的资源时,重复项将被序列化并保存到列中。
要使用 JSON 预设,只需在 Repeater 字段定义中调用 asJson 方法即可:
Repeater::make('Line Items', 'line_items')
->repeatables([
\App\Nova\Repeater\LineItem::make(),
])
->asJson()在使用此预设之前,你应确保资源的中继列的 Eloquent 底层属性已配置为在 Eloquent 模型类中映射到 array(或等价方法):
protected $casts = [
'line_items' => 'array'
];HasMany 预设使用 HasMany 关系通过 Eloquent 存储可重复数据。例如,数据不是以 JSON 格式存储发票的明细项目,而是保存在一个单独的 line_items 数据库表中,并有专门的列映射到重复项中的每个字段。在编辑资源时,Repeater 字段将自动管理这些关系。
要使用 HasMany 预设,只需在 Repeater 字段定义中调用 asHasMany 方法即可:
Repeater::make('Line Items', 'lineItems')
->repeatables([
\App\Nova\Repeater\LineItem::make(),
])
->asHasMany()HasMany 预设要求每个可重复对象通过在 Repeatable 上设置 model 属性来指定它所代表的底层模型。例如,一个 LineItem 可重复项需要指定它所代表的底层 \App\Models\LineItem 模型:
class LineItem extends Repeatable
{
/**
* 可重复模型所代表的基础模型。
*
* @var class-string
*/
public static $model = \App\Models\LineItem::class;
}默认情况下,在编辑使用 HasMany 预设配置的可重复数据时,Nova 会删除所有相关项,并在每次保存资源时重新创建它们。要指示 Nova「向上插入」可重复数据,你应确保在相关模型上有一个唯一标识符列。通常,这将是一个自动递增列或 UUID。然后,你可以使用 uniqueField 方法指定哪一列包含数据库表的唯一键:
/**
* 获取资源显示的字段。
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request)
{
return [
ID::make(),
Repeater::make('Line Items')
->asHasMany()
->uniqueField('uuid')
->repeatables([
\App\Nova\Repeater\LineItem::make()
])
];
}此外,Repeatable 的 fields 方法必须包含一个与 uniqueField 匹配的字段:
use Laravel\Nova\Fields\ID;
/**
* 获取资源显示的字段。
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function fields()
{
return [
ID::hidden('uuid'), // 唯一 ID 字段
// 其他字段...
];
}在本例中,我们使用了 ID::hidden 方法,该方法可阻止 Nova 向用户显示 ID 字段,但在保存或更新资源时仍会将其值传递给 Nova。
虽然 Repeatable 可以使用许多与典型 Nova 资源和操作相同的字段,但它们的行为方式并不相同。例如,不支持 creationRules 和 updateRules 等方法,因为创建和编辑模式的验证规则是相同的。此外,Repeatable内的字段不支持依赖字段(dependsOn)功能。
Repeater 字段允许使用 Nova 支持的所有字段,但以下字段除外:
部分支持以下字段:
Markdown 和 Trix 字段支持用于文本,但目前不支持附件。