logo

中继器字段

测试版说明

此字段当前处于测试版。API 虽然稳定,但在测试期内可能会发生变化。

概述

Repeater 字段允许你创建和编辑可重复的结构化数据,并将该数据存储在 JSON 列或 HasMany 关联中:

php
<?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 字段后,你的资源将拥有一个优雅的界面,用于添加和编辑字段中的可重复项:

Repeater Field

可重复性

一个 Repeatable 对象代表一个 Repeater 字段的可重复数据。它定义了用于可重复项的字段集。当 Repeater 使用 HasMany 预设时,它还可选择定义一个 Eloquent Model 类。

Repeater 中继器字段并不局限于单一的可重复类型。它还支持多种「可重复」类型,这些类型可能包含各自独特的字段集和模型。这些可重复内容可用于创建编辑灵活内容区域的界面,类似于内容管理系统提供的界面。

生成可重复数据

要生成新的中继器 Repeatable,请调用 nova:repeatable Artisan 命令:

sh
php artisan nova:repeatable LineItem

调用上述命令后,Nova 会生成一个新文件 app/Nova/Repeater/LineItem.php。该文件包含一个 fields 方法,你可以在其中列出任何 Nova 支持的字段。例如,下面我们将定义一个 Repeatable 字段,代表发票的行项目:

php
<?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 在删除可重复数据前显示一个确认界面:

php
Repeater::make('Attachments')->repeatables([
	\App\Nova\Repeater\File::make()->confirmRemoval(),
	\App\Nova\Repeater\Note::make(),
	\App\Nova\Repeater\Video::make()->confirmRemoval(),
]),

中继器预设存储

Repeater 中继器字段包括两个开箱即用的存储「预设」:JsonHasMany。每个预设都定义了从数据库中存储和检索可重复数据的方式。

例如,Invoice 资源可以使用 Repeater 字段来编辑发票的行项目。使用 Laravel\Nova\Fields\Repeater\JSON 预设,这些行项目将存储在 line_items JSON 列中。但是,使用 HasMany 预设时,行项目将存储在一个单独的「line_items」数据库表中,每个数据库列都有相应的字段。

JSON 预设

JSON 预设可将重复项存储在数据库中的 JSON 列中。例如,发票的明细项目可存储在 line_items 列中。当使用 JSON 预设保存带有 Repeater 字段的资源时,重复项将被序列化并保存到列中。

要使用 JSON 预设,只需在 Repeater 字段定义中调用 asJson 方法即可:

php
Repeater::make('Line Items', 'line_items')
	->repeatables([
		\App\Nova\Repeater\LineItem::make(),
	])
	->asJson()

在使用此预设之前,你应确保资源的中继列的 Eloquent 底层属性已配置为在 Eloquent 模型类中映射到 array(或等价方法):

php
protected $casts = [
    'line_items' => 'array'
];

HasMany 预设

HasMany 预设使用 HasMany 关系通过 Eloquent 存储可重复数据。例如,数据不是以 JSON 格式存储发票的明细项目,而是保存在一个单独的 line_items 数据库表中,并有专门的列映射到重复项中的每个字段。在编辑资源时,Repeater 字段将自动管理这些关系。

要使用 HasMany 预设,只需在 Repeater 字段定义中调用 asHasMany 方法即可:

php
Repeater::make('Line Items', 'lineItems')
	->repeatables([
		\App\Nova\Repeater\LineItem::make(),
	])
	->asHasMany()

HasMany 预设要求每个可重复对象通过在 Repeatable 上设置 model 属性来指定它所代表的底层模型。例如,一个 LineItem 可重复项需要指定它所代表的底层 \App\Models\LineItem 模型:

php
class LineItem extends Repeatable
{
	/**  
	 * 可重复模型所代表的基础模型。
	 * 
	 * @var class-string
	 */
	public static $model = \App\Models\LineItem::class;
}

使用唯一字段上插可重复数据

默认情况下,在编辑使用 HasMany 预设配置的可重复数据时,Nova 会删除所有相关项,并在每次保存资源时重新创建它们。要指示 Nova「向上插入」可重复数据,你应确保在相关模型上有一个唯一标识符列。通常,这将是一个自动递增列或 UUID。然后,你可以使用 uniqueField 方法指定哪一列包含数据库表的唯一键:

php
/**  
 * 获取资源显示的字段。
 * 
 * @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()
			])
	];
}

此外,Repeatablefields 方法必须包含一个与 uniqueField 匹配的字段:

php
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 资源和操作相同的字段,但它们的行为方式并不相同。例如,不支持 creationRulesupdateRules 等方法,因为创建和编辑模式的验证规则是相同的。此外,Repeatable内的字段不支持依赖字段(dependsOn)功能。

支持的字段

Repeater 字段允许使用 Nova 支持的所有字段,但以下字段除外:

  • HasOne
  • MorphOne
  • HasMany
  • MorphMany
  • BelongsTo
  • MorphTo
  • BelongsToMany
  • MorphToMany

部分支持的字段

部分支持以下字段:

  • File Field
  • Vapor File Field
  • Markdown Field
  • Trix Field

MarkdownTrix 字段支持用于文本,但目前不支持附件。