inspheric / nova-defaultable
创建资源和运行资源操作时Nova字段的默认值。
Requires
- php: >=7.1.0
This package is auto-updated.
Last update: 2024-09-17 22:16:42 UTC
README
在创建资源时填充Nova字段的默认值,并且现在支持资源操作(自v1.2起)!
安装
使用Composer将包安装到使用Nova的Laravel应用程序中
注意:此包目前与Nova版本3.4.0及以上版本不兼容。
composer require inspheric/nova-defaultable
(可选)如果您想在创建资源时使用defaultLast()
方法(见下文),则需要将特质Inspheric\NovaDefaultable\HasDefaultableFields
添加到您的基资源类中(位于app\Nova\Resource.php
)
use Inspheric\NovaDefaultable\HasDefaultableFields; abstract class Resource extends NovaResource { use HasDefaultableFields; // ... }
(可选)如果您想在资源操作中使用defaultLast()
方法,则需要将特质Inspheric\NovaDefaultable\HasDefaultableActionFields
添加到您希望使用可设置字段的所有操作类(位于app\Nova\Actions\
,逐个)中
use Inspheric\NovaDefaultable\HasDefaultableActionFields; class YourAction extends Action { use HasDefaultableActionFields; // ... }
基本用法
在创建资源或运行资源操作时,可能有一些值可以设置为默认值以节省用户时间,而不是每次都需要输入到空白表单中。这可以包括为当前用户拥有的资源填充user_id
,连续填充多个新记录的相同'父'记录,从选中的复选框开始,或填充递增值,例如发票号码。
此包连接到现有字段,并提供两种简单的方法来提供默认值。
注意:以下可设置行为仅适用于资源的'创建'或'附加'表单,或操作请求。在'更新'或'更新附加'请求中,字段不会被设置为默认值;然而,在每次成功的保存请求中,都会存储最后使用值,并在之后的'创建'/'附加'请求中设置为默认值。
设置任何值
在任意标准Nova字段上使用default($value)
方法填充简单值,例如。
Text::make('Name') ->default('Default Name'),
或者
Boolean::make('Active') ->default(true),
default()
方法也可以将回调函数作为第一个参数,该函数将返回要填充的值
Text::make('Name') ->default(function(NovaRequest $request) { return $request->user()->name.'\'s New Resource'; }),
特殊情况
设置BelongsTo字段
要在Nova BelongsTo
字段上使用default()
方法,您可以提供以下之一:
-
一个Eloquent模型的实例,例如。
// $author = $request->user(); BelongsTo::make('Author') ->default($author),
-
相关记录的主键,例如。
// $id = 1; BelongsTo::make('Author') ->default($id),
注意:这只是一个便利,不应依赖于强制执行作者只能编辑他们自己的帖子等。
设置MorphTo字段
要在Nova MorphTo
字段上使用default()
方法,您可以提供以下之一:
-
一个Eloquent模型的实例(最简单的方法),例如。
// $post = App\Post::find(1); MorphTo::make('Commentable') ->types([ Post::class, Video::class, ]) ->default($post),
-
包含主键和形态类型的数组,例如。
// $postId = 1; MorphTo::make('Commentable') ->types(...) ->default([$postId, App\Nova\Post::class]), // The Resource class or class name
或者
MorphTo::make('Commentable') ->types(...) ->default([$postId, App\Post::class]), // The Eloquent model class or class name
或者
MorphTo::make('Commentable') ->types(...) ->default([$postId, 'posts']), // The uriKey string
-
一个Nova资源的实例,例如。
// $postResource = Nova::newResourceFromModel(App\Post::find(1)); MorphTo::make('Commentable') ->types(...) ->default($postResource),
设置最后保存的值
使用defaultLast()
方法缓存此字段的最后保存值,并在下次解决此字段时重新填充它
Text::make('Name') ->defaultLast(),
这将在以下场景中很有用
- 保存(创建或更新)一个资源后,最后值将在创建下一个新资源时重新填充。
- 在某一资源上运行操作后,当在另一资源上运行相同的操作时,最后一个值将被重新填充。
该值将唯一地缓存到用户、资源类别、操作名称(如果适用)、字段和属性。默认缓存时长为一小时,但这可自定义(参见配置)。
例如,这可以用来加速创建多个具有相同父资源的资源,例如。
BelongsTo::make('Author') ->defaultLast(),
注意: defaultLast()
方法会自动处理 MorphTo
字段的形态类型。
注意: 因为在索引视图中运行操作后,“选择操作”下拉菜单不会被刷新,所以如果在同一索引视图中多次运行操作,defaultLast()
无法重新填充每个最后一个值。如果您需要在索引视图中每次都重新填充该值,您可以在操作类上设置属性 $refreshIndex = true
,例如。
class YourAction extends Action { protected $refreshIndex = true; public function handle(ActionFields $fields, Collection $models) { // ... } }
当从索引视图运行操作时,它将返回一个重定向响应以刷新整个页面。如果从详情视图运行操作,则没有影响,因为Nova在每次操作后都会自动刷新页面。
😖 我并不是很喜欢这个解决方案,但想不出替代方案。我很乐意听听其他想法。
注意: 如果您设置了 $refreshIndex = true
,并且您从操作的 handle()
方法返回自己的操作响应,则它将在索引视图中被忽略,因为它被重定向响应覆盖。它在详情视图中将表现得正常。
使用回调显示
两者 default($value, callable $callback = null)
和 defaultLast(callable $callback = null)
方法都可以将回调作为最后一个参数,该回调将在填充之前转换默认值(无论是从缓存检索还是传递给 default()
方法),例如。
$lastInvoiceNumber = auth()->user()->last_invoice_number; Number::make('Invoice Number') ->default($lastInvoiceNumber, function($value, NovaRequest $request) { return $value + 1; // Note: Here the $value came from $lastInvoiceNumber }),
Number::make('Invoice Number') ->defaultLast(function($value, NovaRequest $request) { return $value + 1; // Note: Here the $value came from the cache }),
例如,这可以用来在每次创建新资源时增加一个值。 注意: 这只是一个便利,不应依赖于唯一性或严格顺序增加。
默认最后一个值 或 静态值
如果用户尚未存储“最后一个”值,或者缓存已过期,则 defaultLast()
的值将为空。如果您想要在没有在缓存中找到任何内容时回退到另一个值,您可以在回调中简单地这样做,例如。
BelongsTo::make('Author') ->defaultLast(function($value, NovaRequest $request) { return $value ?: $request->user()->id; }),
在这个例子中,第一条记录的作者默认为当前用户,但后续的每条记录都将默认为最后保存的值。
高级用法
扩展
默认情况下,该软件包支持所有标准Nova字段,这些字段具有单个值且可以在“创建”表单上进行编辑。对于 BelongsTo
和 MorphTo
字段有特定的行为,如上所述。
该软件包不支持任何实现 Laravel\Nova\Contracts\ListableField
的字段,如 HasMany
、BelongsToMany
等,或扩展 Laravel\Nova\Fields\File
的字段,如 File
、Image
或 Avatar
。
任何扩展 Laravel\Nova\Fields\Field
的单值自定义字段 应该 适用于无需自定义。但是,如果需要,您可以扩展行为以支持需要填充额外元数据的自定义字段类型。
DefaultableField::extend()
方法接受您的自定义字段类名和一个回调,该回调接收 $field
(解析的 Field
实例)和 $value
(传递给 default()
或通过 defaultLast()
从缓存检索的值)。
您必须从回调函数中返回 $field
,并建议您使用 $field->withMeta()
发送适当的元数据,以便在字段预先填充,例如在您的 App\Providers\NovaServiceProvider
中。
use Inspheric\NovaDefault\DefaultableField; DefaultableField::extend(YourField::class, function($field, $value) { return $field->withMeta([ 'value' => $value, // This line is usually required to populate the value 'yourMeta' => 'yourValue', // Any additional meta depends on your custom field type ]); });
注意:如果您像上面那样使用 extend()
,则此包的基本默认功能将被完全覆盖,因此您必须确保自己的回调函数正确设置字段值。这通常是通过设置 'value'
元数据键来完成的,但您的字段可能不同,或者可能需要设置额外的元数据键(例如,在 BelongsTo
字段的情况下,可能需要设置 'belongsToId'
)。
您可以将字段类型数组作为第一个参数传递,以便在所有这些字段上使用相同的回调,即:
DefaultableField::extend([YourField::class, YourOtherField::class], function($field, $value) { // ... });
或者,Inspheric\NovaDefault\DefaultableField
是可宏化的,因此您可以添加一个宏,然后使用宏的名称作为字符串作为 extend()
方法的第二个参数,即:
DefaultableField::macro('handleYourField', function($field, $value) { // ... }); DefaultableField::extend(YourField::class, 'handleYourField'); DefaultableField::extend(YourOtherField::class, 'handleYourField');
配置
可以使用以下方式发布配置:
php artisan vendor:publish --provider="Inspheric\NovaDefaultable\DefaultableServiceProvider" --tag="config"
配置文件包含两个键
cache.key
- 用于在缓存中存储“最后”值的键。默认为 'default_last',并将添加到认证用户 ID、资源类和字段属性以实现唯一性。cache.ttl
- 在缓存中存储最后值的时长,以秒为单位。默认为一小时(60 * 60)。