定义好动作后,就可以将其附加到资源上了。Nova 生成的每个资源都包含一个 actions 方法。要将动作附加到资源,只需将其添加到该方法返回的动作数组中即可:
/**
* 获取资源的可用操作。
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function actions(NovaRequest $request)
{
return [
new Actions\EmailAccountProfile
];
}或者,你也可以使用 make 方法来实例化您的动作。传递给 make 方法的任何参数都将传递给动作的构造函数:
/**
* 获取资源的可用操作。
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function actions(NovaRequest $request)
{
return [
Actions\EmailAccountProfile::make()
];
}如果你只想向某些用户公开给定的操作,可以在注册操作时调用 canSee 方法。canSee 方法接受一个闭包,该闭包应返回 true 或 false。闭包将接收传入的 HTTP 请求:
use App\Models\User;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* 获取资源的可用操作。
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function actions(NovaRequest $request)
{
return [
(new Actions\EmailAccountProfile)->canSee(function ($request) {
return $request->user()->can(
'emailAnyAccountProfile', User::class
);
}),
];
}你还可以使用各种请求方法来获取当前选定的资源:
| 方法 | 返回类型 | 描述 |
|---|---|---|
allResourcesSelected | bool | 返回 true 如果 "选择全部" 被勾选. |
selectedResourceIds | \Illuminate\Support\Collection|null | 返回 null 如果 "选择全部" 被勾选 或者 返回所选资源 ID 的集合. |
selectedResources | \Illuminate\Support\Collection|null | 返回 null 如果 "选择全部" 被勾选 或者 返回资源模型集合. |
有时,用户可以 "看到" 某个操作,但只能针对某些资源「运行」该操作。在这种情况下,你可以将 canRun 方法与 canSee 方法结合使用,以全面控制授权。传递给 canRun 方法的回调将接收传入的 HTTP 请求以及用户希望运行该动作的模型:
/**
* 获取资源的可用操作。
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function actions(NovaRequest $request)
{
return [
(new Actions\EmailAccountProfile)->canSee(function ($request) {
return true;
})->canRun(function ($request, $user) {
return $request->user()->can('emailAccountProfile', $user);
}),
];
}除了 canSee 和 canRun 授权方法外,Nova 还将确定资源的相应模型策略是否有 runAction 和 runDestructiveAction 方法。最后,Nova 将根据模型的策略方法确定用户是否有权 update 模型,或在破坏性操作的情况下 delete 模型。
以下步骤清单最能说明授权执行 Nova 行动的优先顺序:
canRun 方法,则使用该方法的返回值。runAction 或 runDestructiveAction 方法,则使用这些方法的返回值。update 或 delete 方法,则使用这些方法的返回值。false。默认情况下,操作在资源索引和详细页面上都可见。不过,你可以在为特定资源注册操作时,通过调用操作的以下方法之一来自定义操作的可见性:
onlyOnIndexexceptOnIndexshowOnIndexonlyOnDetailexceptOnDetailshowOnDetailonlyInlineexceptInlineshowInline内联动作是直接显示在给定资源的索引表行上的动作。在将动作附加到资源时,可通过调用 showInline 方法指定内联操作:
/**
* 获取资源的可用操作。
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function actions(NovaRequest $request)
{
return [
(new ConsolidateTransaction())->showInline()
];
}通常情况下,操作是针对在资源索引或详细信息页面上选择的资源执行的。不过,有时你可能会有一个不需要任何资源/模型即可运行的操作。在这种情况下,你可以在注册动作时调用 standalone 方法,将动作注册为「独立」动作。这些动作总是在其 handle 方法中接收模型的空集合:
/**
* 获取资源的可用操作。
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function actions(NovaRequest $request)
{
return [
Actions\InviteUser::make()->standalone()
];
}有时,你可能有只能在单个资源/模型上运行的动作。通过将动作注册为 sole 操作,Nova 将只在选择单一资源时显示该动作。单一操作仍会在其 handle 方法中接收一个集合,但该集合将只包含一个模型:
/**
* 获取资源的可用操作。
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function actions(NovaRequest $request)
{
return [
Actions\BanUser::make()->sole()
];
}通常,动作会对资源进行操作。不过,你也可以将动作附加到 belongsToMany 字段,这样它们就可以对透视表/中间表记录进行操作。为此,你可以将 actions 方法链到字段的定义上:
BelongsToMany::make('Roles')
->actions(fn () => [new Actions\MarkAsActive]),将动作附加到字段后,你就可以在父资源详细信息页面的关系索引中选择动作并执行它。
默认情况下,操作下拉菜单中的中间表动作将分组为 "Pivot",但你可以使用 referToPivotAs 方法自定义此名称:
BelongsToMany::make('Roles')
->actions(fn () => [new Actions\MarkAsActive])
->referToPivotAs('Role Assignment'),闭包动作允许你创建动作,而无需将动作定义为一个单独的类。要定义闭包动作,请调用 Action 类上的 using 工厂方法,并传递动作名称和闭包。提供给 using 方法的闭包接收的参数与专用动作的 handle 方法相同:
public function actions()
{
return [
Action::using('Deactivate User', function (ActionFields $fields, Collection $models) {
$models->each->update(['active' => false]);
}),
];
}队列动作闭包
闭包动作无法使用 Laravel 提供的 ShouldQueue 特性,因此不可队列化。
使用 Nova 时,定义动作来完成下载文件、重定向用户或打开新窗口等简单任务是很常见的。幸运的是,Nova 提供了静态操作,让你无需编写专用操作即可完成各种常见任务。
redirect 操作会将用户重定向到外部 URL。要创建 redirect 操作,请输入操作名称和要将用户重定向到的 URL:
public function actions()
{
return [
Action::redirect('Visit Stripe Dashboard', 'https://stripe.com')->standalone(),
];
}visit 操作会将用户推送到 Nova 的内部页面。要创建 visit 操作,请输入操作名称和希望用户访问的路径:
use Laravel\Nova\Nova;
public function actions()
{
return [
Action::visit('View Logs', Nova::url('/logs'))->standalone(),
];
}danger 操作会向用户显示错误提示通知。例如,你的 Nova 应用程序可能有一个以前可用但现在已不再可用的操作,为避免混乱,你可能希望通知用户该操作已被删除。为此,请将动作名称和要显示给用户的信息传递给用户:
public function actions()
{
return [
Action::danger('Disable User Account', 'This action is no longer available!'),
];
}通过 modal 操作,你可以向用户显示自定义模式。要创建 modal 操作,需要传递操作名称、自定义 Vue 组件以及应提供给组件的任何其他数据:
public function actions()
{
return [
Action::modal('Download User Summary', 'UserSummary', function ($user) {
return [
'user_id' => $user->getKey(),
];
})->sole(),
];
}openInNewTab 操作会在新的浏览器标签页中打开一个 URL。要创建 openInNewTab 操作,请输入操作名称和应在新浏览器标签页中打开的 URL:
public function actions()
{
return [
Action::openInNewTab('Visit Stripe Dashboard', 'https://stripe.com')->standalone(),
];
}你也可以通过定义唯一操作来配置资源的唯一 URL:
Action::openInNewTab('Visit User Profile', function ($user) {
return route('user.profile', $user);
})->sole(),downloadUrl操作会下载指定 URL 上的文件。要创建 downloadUrl 操作,请输入操作名称和要下载文件的 URL:
public function actions()
{
return [
Action::downloadUrl('Download Users Summaries', function () {
return route('users.summaries');
})->standalone(),
];
}在运行动作时,通常会向用户显示一个确认模式,让他们有机会取消待执行的动作。为了指示确认模式窗应全屏显示,你可以在使用给定资源注册动作时调用 fullscreen 方法:
/**
* 获取资源的可用操作。
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function actions(NovaRequest $request)
{
return [
Actions\EmailAccountProfile::make()->fullscreen()
];
}此外,你还可以使用 size 方法进一步自定义自定义模式窗体的最大宽度:
/**
* 获取资源的可用操作。
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function actions(NovaRequest $request)
{
return [
// "sm", "md", "lg", "xl", "2xl", "3xl", "4xl", "5xl", "6xl", or "7xl"...
Actions\EmailAccountProfile::make()->size('7xl')
];
}要禁用动作确认模式并立即运行动作,可以在使用给定资源注册动作时调用 withoutConfirmation 方法:
/**
* 获取资源的可用操作。
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function actions(NovaRequest $request)
{
return [
Actions\EmailAccountProfile::make()->withoutConfirmation()
];
}