定义 Actions
Nova操作使您可以在一个或多个Eloquent模型上执行自定义任务。例如,您可以编写一个操作,向用户发送一封电子邮件,其中包含他们所请求的帐户数据。或者,您可以编写一个操作来将一组记录转移给另一个用户。
将操作附加到资源定义后,可以从资源的索引或详细信息屏幕启动该操作:

如果启用了在资源的表行上显示的操作,则可以从资源的操作下拉菜单中启动该操作。这些称为“内联操作”:

#概述
Nova动作可以使用nova:actionArtisan命令生成。默认情况下,所有操作都放置在app/Nova/Actions目录中:
php artisan nova:action EmailAccountProfile
您可以通过传递以下选项来生成破坏性操作--destructive:
php artisan nova:action DeleteUserData --destructive
要了解如何定义Nova动作,我们来看一个示例。在此示例中,我们将定义一个向用户或用户组发送电子邮件的操作:
<?php
namespace App\Nova\Actions;
use App\AccountData;
use Illuminate\Bus\Queueable;
use Laravel\Nova\Actions\Action;
use Illuminate\Support\Collection;
use Laravel\Nova\Fields\ActionFields;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class EmailAccountProfile extends Action
{
  use InteractsWithQueue, Queueable;
  /**
   * Perform the action on the given models.
   *
   * @param  \Laravel\Nova\Fields\ActionFields  $fields
   * @param  \Illuminate\Support\Collection  $models
   * @return mixed
   */
  public function handle(ActionFields $fields, Collection $models)
  {
    foreach ($models as $model) {
      (new AccountData($model))->send();
    }
  }
  /**
   * Get the fields available on the action.
   *
   * @return array
   */
  public function fields()
  {
    return [];
  }
}
动作最重要的方法是handle方法。该handle方法接收该操作所附的任何字段的值,以及选定模型的集合。即使仅针对单个模型执行操作,该handle方法也始终接收Collection模型。
在该handle方法内,您可以执行完成操作所需的任何任务。您可以自由更新数据库记录,发送电子邮件,致电其他服务等。
#动作可见度
默认情况下,操作在资源索引和详细信息屏幕上都是可见的。此外,默认情况下,内联操作从表行的操作下拉列表中隐藏。定义动作时,可以通过在动作上设置以下方法之一来指定其可见性:
onlyOnIndexexceptOnIndexshowOnIndexonlyOnDetailexceptOnDetailshowOnDetailonlyOnTableRowexceptOnTableRowshowOnTableRow
#破坏性行动
您可以通过让动作类继承自来将某动作指定为破坏性或危险动作Laravel\Nova\Actions\DestructiveAction。这会将操作的确认按钮的颜色更改为红色:

破坏性行动与政策
将破坏性操作添加到具有关联授权策略的资源时,该策略的delete方法必须返回true才能运行该操作。
#行动领域
有时,您可能希望在分派操作之前从用户那里收集其他信息。因此,Nova允许您将Nova支持的大多数字段直接附加到动作上。启动操作时,Nova将提示用户提供以下字段的输入:

要将字段添加到动作,请将字段添加到该动作的fields方法返回的字段数组中:
use Laravel\Nova\Fields\Text;
/**
 * Get the fields available on the action.
 *
 * @return array
 */
public function fields()
{
    return [
        Text::make('Subject'),
    ];
}
最后,在您的操作handle方法内,您可以使用提供的ActionFields实例上的动态访问器来访问字段:
/**
 * Perform the action on the given models.
 *
 * @param  \Laravel\Nova\Fields\ActionFields  $fields
 * @param  \Illuminate\Support\Collection  $models
 * @return mixed
 */
public function handle(ActionFields $fields, Collection $models)
{
    foreach ($models as $model) {
        (new AccountData($model))->send($fields->subject);
    }
}
#动作模式自定义
默认情况下,操作将在运行前要求用户确认。您可以自定义确认消息,确认按钮和取消按钮,以在执行操作之前为用户提供更多上下文。这是通过指定的完成confirmText,confirmButtonText以及cancelButtonText定义操作时的方法:
/**
 * Get the actions available for the resource.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
public function actions(Request $request)
{
    return [
        (new Actions\ActivateUser)
            ->confirmText('Are you sure you want to activate this user?')
            ->confirmButtonText('Activate')
            ->cancelButtonText("Don't activate"),
    ];
}
这将自定义模式,如下所示:

#动作回应
通常,执行操作时,Nova UI中会显示通用的“成功”消息。但是,您可以使用Action类上的各种方法来自定义此响应。
要显示自定义的“成功”消息,可以Action::message从您的handle方法中返回该方法的结果:
/**
 * Perform the action on the given models.
 *
 * @param  \Laravel\Nova\Fields\ActionFields  $fields
 * @param  \Illuminate\Support\Collection  $models
 * @return mixed
 */
public function handle(ActionFields $fields, Collection $models)
{
    // ...
    return Action::message('It worked!');
}
要返回红色的“危险”消息,可以使用以下Action::danger方法:
return Action::danger('Something went wrong!');
#重定向响应
要在执行操作后将用户重定向到一个全新的位置,可以使用以下Action::redirect方法:
return Action::redirect('https://example.com');
要将用户重定向到内部路由,请使用以下Action::push方法:
return Action::push('/resources/posts/new', [
  'viaResource' => 'users',
  'viaResourceId' => 1,
  'viaRelationship' => 'posts'
]);
#下载回应
要在执行操作后启动文件下载,可以使用该Action::download方法。该download方法将要下载的文件的URL作为其第一个参数,并将文件的所需名称作为其第二个参数:
return Action::download('https://example.com/invoice.pdf', 'Invoice.pdf');
#排队的动作
有时,您可能需要花费一些时间才能完成运行。出于这个原因,Nova让您排队行动很容易。要指示Nova将操作排入队列而不是同步运行,请在ShouldQueue界面上标记该操作:
<?php
namespace App\Nova\Actions;
use App\AccountData;
use Illuminate\Bus\Queueable;
use Laravel\Nova\Actions\Action;
use Illuminate\Support\Collection;
use Laravel\Nova\Fields\ActionFields;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class EmailAccountProfile extends Action implements ShouldQueue
{
  use InteractsWithQueue, Queueable;
  // ...
}
使用排队操作时,请不要忘记为应用程序配置和启动队列工作器。否则,您的操作将不会被处理。
排队的操作文件
目前,Nova不支持将File字段附加到排队的操作。如果需要将File字段附加到操作,则该操作必须同步运行。
#自定义连接和队列
您可以通过在操作上定义$connection和$queue属性来自定义操作排队的队列连接和队列名称:
/**
 * The name of the connection the job should be sent to.
 *
 * @var string|null
 */
public $connection = 'redis';
/**
 * The name of the queue the job should be sent to.
 *
 * @var string|null
 */
public $queue = 'emails';
#动作日志
查看针对资源运行的操作的日志通常很有用。此外,在对操作进行排队时,知道它们何时真正完成通常很重要。值得庆幸的是,Nova通过将Laravel\Nova\Actions\Actionable特征附加到资源的相应Eloquent模型来轻松地向该资源添加操作日志。
例如,我们可以将Laravel\Nova\Actions\Actionable特征附加到UserEloquent模型:
<?php
namespace App;
use Laravel\Nova\Actions\Actionable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
  use Actionable, Notifiable;
  // ...
}
将特征附加到模型后,Nova将自动开始在资源的详细信息屏幕底部显示操作日志:

#禁用操作日志
如果您不想在操作日志中记录操作,则可以通过withoutActionEvents在操作类上添加属性来禁用此行为:
/**
 * Disables action log events for this action.
 *
 * @var bool
 */
public $withoutActionEvents = true;
或者,使用该withoutActionEvents方法,可以在将操作附加到资源时为该操作禁用操作日志:
/**
 * Get the actions available for the resource.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
public function actions(Request $request)
{
    return [
        (new SomeAction)->withoutActionEvents()
    ];
}
#排队的动作状态
当排队的操作正在运行时,您可以为通过其模型集合传递给该操作的任何模型更新该操作的“状态”。例如,您可以使用操作的markAsFinished方法来指示该操作已完成对特定模型的处理:
/**
 * Perform the action on the given models.
 *
 * @param  \Laravel\Nova\Fields\ActionFields  $fields
 * @param  \Illuminate\Support\Collection  $models
 * @return mixed
 */
public function handle(ActionFields $fields, Collection $models)
{
    foreach ($models as $model) {
        (new AccountData($model))->send($fields->subject);
        $this->markAsFinished($model);
    }
}
或者,如果您想指示某个动作对于给定的模型“失败”,则可以使用以下markAsFailed方法:
/**
 * Perform the action on the given models.
 *
 * @param  \Laravel\Nova\Fields\ActionFields  $fields
 * @param  \Illuminate\Support\Collection  $models
 * @return mixed
 */
public function handle(ActionFields $fields, Collection $models)
{
    foreach ($models as $model) {
        try {
            (new AccountData($model))->send($fields->subject);
        } catch (Exception $e) {
            $this->markAsFailed($model, $e);
        }
    }
}
                    
                    
                                            本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
          
Laravel Nova 中文文档
                    
                    
            
            
                关于 LearnKu
              
                    
                    
                    
 
推荐文章: