logo

注册动作

定义好动作后,就可以将其附加到资源上了。Nova 生成的每个资源都包含一个 actions 方法。要将动作附加到资源,只需将其添加到该方法返回的动作数组中即可:

php
/**
 * 获取资源的可用操作。
 *
 * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
 * @return array
 */
public function actions(NovaRequest $request)
{
    return [
        new Actions\EmailAccountProfile
    ];
}

或者,你也可以使用 make 方法来实例化您的动作。传递给 make 方法的任何参数都将传递给动作的构造函数:

php
/**
 * 获取资源的可用操作。
 *
 * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
 * @return array
 */
public function actions(NovaRequest $request)
{
    return [
        Actions\EmailAccountProfile::make()
    ];
}

授权

如果你只想向某些用户公开给定的操作,可以在注册操作时调用 canSee 方法。canSee 方法接受一个闭包,该闭包应返回 truefalse。闭包将接收传入的 HTTP 请求:

php
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
            );
        }),
    ];
}

你还可以使用各种请求方法来获取当前选定的资源:

方法返回类型描述
allResourcesSelectedbool返回 true 如果 "选择全部" 被勾选.
selectedResourceIds\Illuminate\Support\Collection|null返回 null 如果 "选择全部" 被勾选 或者 返回所选资源 ID 的集合.
selectedResources\Illuminate\Support\Collection|null返回 null 如果 "选择全部" 被勾选 或者 返回资源模型集合.

资源特定授权

有时,用户可以 "看到" 某个操作,但只能针对某些资源「运行」该操作。在这种情况下,你可以将 canRun 方法与 canSee 方法结合使用,以全面控制授权。传递给 canRun 方法的回调将接收传入的 HTTP 请求以及用户希望运行该动作的模型:

php
/**
 * 获取资源的可用操作。
 *
 * @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);
        }),
    ];
}

通过资源策略授权

除了 canSeecanRun 授权方法外,Nova 还将确定资源的相应模型策略是否有 runActionrunDestructiveAction 方法。最后,Nova 将根据模型的策略方法确定用户是否有权 update 模型,或在破坏性操作的情况下 delete 模型。

以下步骤清单最能说明授权执行 Nova 行动的优先顺序:

  1. 如果定义了动作的 canRun 方法,则使用该方法的返回值。
  2. 如果定义了底层模型策略的 runActionrunDestructiveAction 方法,则使用这些方法的返回值。
  3. 如果定义了基础模型策略的 updatedelete 方法,则使用这些方法的返回值。
  4. 否则返回 false

动作可见性

默认情况下,操作在资源索引和详细页面上都可见。不过,你可以在为特定资源注册操作时,通过调用操作的以下方法之一来自定义操作的可见性:

  • onlyOnIndex
  • exceptOnIndex
  • showOnIndex
  • onlyOnDetail
  • exceptOnDetail
  • showOnDetail
  • onlyInline
  • exceptInline
  • showInline

内联动作

内联动作是直接显示在给定资源的索引表行上的动作。在将动作附加到资源时,可通过调用 showInline 方法指定内联操作:

php
/**
 * 获取资源的可用操作。
 *
 * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
 * @return array
 */
public function actions(NovaRequest $request)
{
    return [
        (new ConsolidateTransaction())->showInline()
    ];
}

独立的动作

通常情况下,操作是针对在资源索引或详细信息页面上选择的资源执行的。不过,有时你可能会有一个不需要任何资源/模型即可运行的操作。在这种情况下,你可以在注册动作时调用 standalone 方法,将动作注册为「独立」动作。这些动作总是在其 handle 方法中接收模型的空集合:

php
/**
 * 获取资源的可用操作。
 *
 * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
 * @return array
 */
public function actions(NovaRequest $request)
{
    return [
        Actions\InviteUser::make()->standalone()
    ];
}

单一执行动作

有时,你可能有只能在单个资源/模型上运行的动作。通过将动作注册为 sole 操作,Nova 将只在选择单一资源时显示该动作。单一操作仍会在其 handle 方法中接收一个集合,但该集合将只包含一个模型:

php
/**
 * 获取资源的可用操作。
 *
 * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
 * @return array
 */
public function actions(NovaRequest $request)
{
    return [
        Actions\BanUser::make()->sole()
    ];
}

中间表动作

通常,动作会对资源进行操作。不过,你也可以将动作附加到 belongsToMany 字段,这样它们就可以对透视表/中间表记录进行操作。为此,你可以将 actions 方法链到字段的定义上:

php
BelongsToMany::make('Roles')
    ->actions(fn () => [new Actions\MarkAsActive]),

将动作附加到字段后,你就可以在父资源详细信息页面的关系索引中选择动作并执行它。

自定义中间表动作名称

默认情况下,操作下拉菜单中的中间表动作将分组为 "Pivot",但你可以使用 referToPivotAs 方法自定义此名称:

php
BelongsToMany::make('Roles')
    ->actions(fn () => [new Actions\MarkAsActive])
    ->referToPivotAs('Role Assignment'),

动作闭包

闭包动作允许你创建动作,而无需将动作定义为一个单独的类。要定义闭包动作,请调用 Action 类上的 using 工厂方法,并传递动作名称和闭包。提供给 using 方法的闭包接收的参数与专用动作的 handle 方法相同:

php
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:

php
public function actions()
{
    return [
        Action::redirect('Visit Stripe Dashboard', 'https://stripe.com')->standalone(),
    ];
}

访问动作

visit 操作会将用户推送到 Nova 的内部页面。要创建 visit 操作,请输入操作名称和希望用户访问的路径:

php
use Laravel\Nova\Nova;

public function actions()
{
    return [
        Action::visit('View Logs', Nova::url('/logs'))->standalone(),
    ];
}

危险动作

danger 操作会向用户显示错误提示通知。例如,你的 Nova 应用程序可能有一个以前可用但现在已不再可用的操作,为避免混乱,你可能希望通知用户该操作已被删除。为此,请将动作名称和要显示给用户的信息传递给用户:

php
public function actions()
{
    return [
        Action::danger('Disable User Account', 'This action is no longer available!'),
    ];
}

自定义模态动作

通过 modal 操作,你可以向用户显示自定义模式。要创建 modal 操作,需要传递操作名称、自定义 Vue 组件以及应提供给组件的任何其他数据:

php
public function actions()
{
    return [
        Action::modal('Download User Summary', 'UserSummary', function ($user) {
            return [
                'user_id' => $user->getKey(),
            ];
        })->sole(),
    ];
}

在新标签页中打开 URL

openInNewTab 操作会在新的浏览器标签页中打开一个 URL。要创建 openInNewTab 操作,请输入操作名称和应在新浏览器标签页中打开的 URL:

php
public function actions()
{
    return [
        Action::openInNewTab('Visit Stripe Dashboard', 'https://stripe.com')->standalone(),
    ];
}

你也可以通过定义唯一操作来配置资源的唯一 URL:

php
Action::openInNewTab('Visit User Profile', function ($user) {
    return route('user.profile', $user);
})->sole(),

下载文件

downloadUrl操作会下载指定 URL 上的文件。要创建 downloadUrl 操作,请输入操作名称和要下载文件的 URL:

php
public function actions()
{
    return [
        Action::downloadUrl('Download Users Summaries', function () {
            return route('users.summaries');
        })->standalone(),
    ];
}

动作确认模式

全屏/自定义模态尺寸

在运行动作时,通常会向用户显示一个确认模式,让他们有机会取消待执行的动作。为了指示确认模式窗应全屏显示,你可以在使用给定资源注册动作时调用 fullscreen 方法:

php
/**
 * 获取资源的可用操作。
 *
 * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
 * @return array
 */
public function actions(NovaRequest $request)
{
    return [
        Actions\EmailAccountProfile::make()->fullscreen()
    ];
}

此外,你还可以使用 size 方法进一步自定义自定义模式窗体的最大宽度:

php
/**
 * 获取资源的可用操作。
 *
 * @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 方法:

php
/**
 * 获取资源的可用操作。
 *
 * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
 * @return array
 */
public function actions(NovaRequest $request)
{
    return [
        Actions\EmailAccountProfile::make()->withoutConfirmation()
    ];
}