Laravel Nova 定義 Actions

2023-02-16 17:09 更新

Nova 操作使您可以在一個或多個 Eloquent 模型上執(zhí)行自定義任務(wù)。例如,您可以編寫一個操作,向用戶發(fā)送一封電子郵件,其中包含他們所請求的帳戶數(shù)據(jù)?;蛘?,您可以編寫一個操作來將一組記錄轉(zhuǎn)移給另一個用戶。

將操作附加到資源定義后,可以從資源的索引或詳細(xì)信息屏幕啟動該操作:


如果啟用了在資源的表行上顯示的操作,則可以從資源的操作下拉菜單中啟動該操作。這些稱為 “內(nèi)聯(lián)操作”:


概述

Nova 動作可以使用 nova:actionArtisan 命令生成。默認(rèn)情況下,所有操作都放置在 app/Nova/Actions 目錄中:

php artisan nova:action EmailAccountProfile

您可以通過傳遞以下選項來生成破壞性操作--destructive

php artisan nova:action DeleteUserData --destructive

要了解如何定義 Nova 動作,我們來看一個示例。在此示例中,我們將定義一個向用戶或用戶組發(fā)送電子郵件的操作:

<?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 方法接收該操作所附的任何字段的值,以及選定模型的集合。即使僅針對單個模型執(zhí)行操作,該 handle 方法也始終接收 Collection 模型。

在該 handle 方法內(nèi),您可以執(zhí)行完成操作所需的任何任務(wù)。您可以自由更新數(shù)據(jù)庫記錄,發(fā)送電子郵件,致電其他服務(wù)等。

動作可見度

默認(rèn)情況下,操作在資源索引和詳細(xì)信息屏幕上都是可見的。此外,默認(rèn)情況下,內(nèi)聯(lián)操作從表行的操作下拉列表中隱藏。定義動作時,可以通過在動作上設(shè)置以下方法之一來指定其可見性:

  • onlyOnIndex
  • exceptOnIndex
  • showOnIndex
  • onlyOnDetail
  • exceptOnDetail
  • showOnDetail
  • onlyOnTableRow
  • exceptOnTableRow
  • showOnTableRow

破壞性行動

您可以通過讓動作類繼承自來將某動作指定為破壞性或危險動作 Laravel\Nova\Actions\DestructiveAction。這會將操作的確認(rèn)按鈕的顏色更改為紅色:


破壞性行動與政策

將破壞性操作添加到具有關(guān)聯(lián)授權(quán)策略的資源時,該策略的 delete 方法必須返回 true 才能運行該操作。

行動領(lǐng)域

有時,您可能希望在分派操作之前從用戶那里收集其他信息。因此,Nova 允許您將 Nova 支持的大多數(shù)字段直接附加到動作上。啟動操作時,Nova 將提示用戶提供以下字段的輸入:


要將字段添加到動作,請將字段添加到該動作的 fields 方法返回的字段數(shù)組中:

use Laravel\Nova\Fields\Text;

/**
 * Get the fields available on the action.
 *
 * @return array
 */
public function fields()
{
    return [
        Text::make('Subject'),
    ];
}

最后,在您的操作 handle 方法內(nèi),您可以使用提供的 ActionFields 實例上的動態(tài)訪問器來訪問字段:

/**
 * 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);
    }
}

動作模式自定義

默認(rèn)情況下,操作將在運行前要求用戶確認(rèn)。您可以自定義確認(rèn)消息,確認(rèn)按鈕和取消按鈕,以在執(zhí)行操作之前為用戶提供更多上下文。這是通過指定的完成 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"),
    ];
}

這將自定義模式,如下所示:


動作回應(yīng)

通常,執(zhí)行操作時,Nova UI 中會顯示通用的 “成功” 消息。但是,您可以使用 Action 類上的各種方法來自定義此響應(yīng)。

要顯示自定義的 “成功” 消息,可以 Action::message 從您的 handle 方法中返回該方法的結(jié)果:

/**
 * 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!');

重定向響應(yīng)

要在執(zhí)行操作后將用戶重定向到一個全新的位置,可以使用以下 Action::redirect 方法:

return Action::redirect('https://example.com');

要將用戶重定向到內(nèi)部路由,請使用以下 Action::push 方法:

return Action::push('/resources/posts/new', [
  'viaResource' => 'users',
  'viaResourceId' => 1,
  'viaRelationship' => 'posts'
]);

下載回應(yīng)

要在執(zhí)行操作后啟動文件下載,可以使用該 Action::download 方法。該 download 方法將要下載的文件的 URL 作為其第一個參數(shù),并將文件的所需名稱作為其第二個參數(shù):

return Action::download('https://example.com/invoice.pdf', 'Invoice.pdf');

排隊的動作

有時,您可能需要花費一些時間才能完成運行。出于這個原因,Nova 讓您排隊行動很容易。要指示 Nova 將操作排入隊列而不是同步運行,請在 ShouldQueue 界面上標(biāo)記該操作:

<?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;

  // ...
}

使用排隊操作時,請不要忘記為應(yīng)用程序配置和啟動隊列工作器。否則,您的操作將不會被處理。

排隊的操作文件

目前,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 特征附加到資源的相應(yīng) 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 將自動開始在資源的詳細(xì)信息屏幕底部顯示操作日志:


禁用操作日志

如果您不想在操作日志中記錄操作,則可以通過 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()
    ];
}

排隊的動作狀態(tài)

當(dāng)排隊的操作正在運行時,您可以為通過其模型集合傳遞給該操作的任何模型更新該操作的 “狀態(tài)”。例如,您可以使用操作的 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);
        }
    }
}


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號