6

枚举是最近引入 PHP 的。我正在一个 laravel 项目中尝试它们。我在这里有我的枚举类:

namespace App\Enums;

enum AlertType
{
    case SUCCESS;
    case ERROR;
}

我正在尝试创建一个警报类,它将采用构造函数中的枚举来设置警报的严重性,这将决定它呈现给用户的颜色。这是那个类:

<?php

namespace App\View\Components;

use App\Enums\AlertType;
use Illuminate\View\Component;

class Alert extends Component
{
    public string $contextClass;

    public function __construct(public string $message, AlertType $alertType = AlertType::SUCCESS)
    {
        $this->setContextClassFromAlertType($alertType);
    }

    public function setContextClassFromAlertType(AlertType $alertType)
    {
        $this->contextClass = ($alertType === AlertType::SUCCESS ? 'success' : 'error');
    }

    public function getClassListFromType()
    {
        return [
            'border-' . $this->contextClass,
            'text-' . $this->contextClass
        ];
    }

    public function render()
    {
        return view('components.alert', [
            'class' => implode(' ', $this->getClassListFromType())
        ]);
    }
}

此警报将在使用 Laravel Livewire 和刀片组件构建的登录表单中使用:

<form class="grid grid-cols-min-auto-1 gap-x-2" id="login" action="/login" method="post">
    <x-alert :message="$errorMessage"/>
    @csrf
    <label for="email" class="mb-2 text-lg text-sans w-min mt-2 font-thin">Email</label>
    <x-basic-input wire:model="email" placeholder="{{ $emailPlaceholder }}"/>
    <label for="password" class="mb-2 text-lg text-sans w-min mt-2 font-thin">Password</label>
    <x-basic-input wire:model="password"/>
</form>

当我来显示登录表单时,出现以下错误:

Cannot instantiate enum App\Enums\AlertType (View: /resources/views/livewire/forms/login.blade.php)

我认为我在 Alert 组件中的枚举使用有问题,但我不确定在哪里。谁能指出我正确的方向。我已经查看了枚举的 rfc,但我看不到任何明显的我做错的事情

4

2 回答 2

3

我能够重现此错误;在我的情况下,堆栈跟踪返回到barryvdh/laravel-debugbar包,不确定这对你来说是否相同。我能够通过将 enum 更改为支持的 enum来解决它。

无论如何,我都建议进行此更改,因为我希望在很多情况下字符串比枚举实例更容易使用。(虽然 TBH 这看起来像是尝试使用一个新功能,只是因为它在那里,而不是因为它有意义。)

namespace App\Enums;

enum AlertType: string
{
    case SUCCESS = 'success';
    case ERROR = 'error';
    case INFO = 'info';
}

在支持的枚举中,每个项目都有一个可以使用value属性访问的字符串表示,我们在构造函数中执行此操作:

<?php

namespace App\View\Components;

use App\Enums\AlertType;
use Illuminate\View\Component;

class Alert extends Component
{
    public string $contextClass;

    public function __construct(
        public string $message,
        AlertType $alertType = AlertType::SUCCESS,
    )
    {
        $this->contextClass = $alertType->value;
    }

    public function getClassListFromType()
    {
        return [
            'border-' . $this->contextClass,
            'text-' . $this->contextClass
        ];
    }

    public function render()
    {
        return view('components.alert', [
            'class' => implode(' ', $this->getClassListFromType())
        ]);
    }
}

您现在可以使用from()ortryFrom()方法来增加保存在变量中的警报类型的灵活性。例如:

<x-alert :message="$errorMessage" :type="App\Enums\AlertType::from($errorType)"/>
于 2021-12-29T18:38:34.097 回答
0

我认为这里的问题是由于依赖注入。在构造函数中,我正在键入一个枚举,因此 Laravel 容器试图创建该类的一个实例以传递,因为枚举是可实例化的,所以它不起作用。

如果我更新容器以手动解析 typehinted 实例,如下所示:

$this->app->bind(Alert::class, function ($app) {
    return new Alert('this is a message', AlertType::SUCCESS);
});

然后问题得到解决,它按预期工作。我需要改变我在这里使用枚举的方式,因为@miken32 建议使用支持的枚举并依赖字符串。否则,我需要为要传递枚举的每个方法覆盖容器注入。

于 2022-01-01T20:42:09.840 回答