Проблемы с Laravel livewire при использовании мутаторов и аксессуаров

Я пытаюсь ввести модель, свойства которой являются числами с плавающей запятой, которые хранятся в базе данных в определенном блоке, например. для объема: литров. Я хочу, чтобы пользователь мог видеть и вводить значения в единицах по своему выбору, например. Галлоны США вместо литров, что позволяет в любой момент выбрать другую единицу измерения, например Пинта США или гектолитр. Для этого я разрешаю каждому пользователю хранить набор единиц для различных физических величин.

Что я собираюсь сделать, так это создать мутаторы и вспомогательные средства на основе того, что пользователь выбрал для преобразования пользовательских единиц в литры перед сохранением и преобразования литров в пользовательские единицы при получении. Вот выдержка из моей модели

    class Equipment extends Model
{
    use HasFactory;
    protected $table = "equipments";
    protected $fillable = [
        'name',
        ...
        'boiler_volume',
        'boiler_dead_volume',
        ...
    ];

    protected $appends = ['boiler_volume','boiler_dead_volume'];

    //get the user's unit transformation factor (it works and return a float number)
    private function getKVolume()
    {
        $units = Unitset::where('user_id', auth()->user()->id)->first();
        return explode(',', $units->volume)[2];
    }

    //BOILER-----------------
    public function setBoilerVolumeAttribute($value)
    {
        if (is_numeric($value) and $value !== null and $value != 0) {
            $this->attributes['boiler_volume'] = $value * $this->getKVolume();
        }
    }
    public function getBoilerVolumeAttribute($value)
    {
        if (is_numeric($value)) {
            return $value / $this->getKVolume();
        }
    }
    //------------------
    public function setBoilerDeadVolumeAttribute($value)
    {
        if (is_numeric($value) and $value !== null and $value != 0) {
            $this->attributes['boiler_dead_volume'] = $value * $this->getKVolume();
        }
    }

    public function getBoilerDeadVolumeAttribute($value)
    {
        if (is_numeric($value)) {
            return $value / $this->getKVolume();
        }
    }

Теперь перейдем к правилам в компоненте livewire.

protected $rules =[
    ...
    'equipment.boiler_volume'=>'required|numeric',
    'equipment.boiler_dead_volume'=>'required|numeric',
    ...
];

и, наконец, соответствующая часть формы на виде лезвия

<x-input.group label="{{ __('Boiler Tun Volume ') }} ({{ explode(',', $unitset->volume)[0] }})" for='
            boiler_volume' :error="$errors->first('equipment.boiler_volume')"
        class="flex flex-col w-full p-2 border border-jbrown-peachpuf bg-jbrown-darker rounded-md ">
        <x-input.text wire:model.lazy="equipment.boiler_volume" type="number" step="0.001"
            class="border border-red-200 bg-red-100" name="boiler_volume" id="boiler_volume" value="" />
    </x-input.group>
    <x-input.group label="{{ __('Boiler Tun Dead Volume ') }} ({{ explode(',', $unitset->volume)[0] }})" for='
            boiler_dead_volume' :error="$errors->first('equipment.boilen_dead_volume')"
        class="flex flex-col w-full p-2 border border-jbrown-peachpuf bg-jbrown-darker rounded-md ">
        <x-input.text wire:model="equipment.boiler_dead_volume" type="text" class="border border-red-200 bg-red-100"
            name="boiler_dead_volume" id="boiler_dead_volume" value="" />
    </x-input.group>

Как вы можете видеть, первый ввод использует числовой тип, а второй - текстовый. Это только для объяснения, поскольку проблема одинакова как с типом ввода числа, так и с типом ввода текста. Но теперь позвольте мне сказать, в чем проблема.

В чем проблема? Проблема в том, что для второго поля equipment.boiler_dead_volume, как только вы ввели значение, вы не можете его удалить (например, для исправления). Вы можете удалить все цифры, которые вы ввели, кроме первой. Тем не менее, если вы используете клавишу со стрелкой влево, чтобы поместить курсор в начало поля, вы можете ввести новое значение, а затем удалить последний символ, но никогда не оставляйте поле пустым. Это довольно раздражает пользователя.

Я должен добавить, что такого поведения не существует, если не используются мутаторы и аксессоры. Кроме того, первое поле для котел_волю нормально работает даже с аксессором и мутатором. Последнее и последнее, все остальные поля ведут себя так же, т.е. неправильно.

Примечание. Строка

 protected $appends=...

ничего не меняет.

Другое странное поведение. Посмотрев на мутаторы и методы доступа, вы можете увидеть, что некоторые проверяют, является ли значение числовым, а не нулевым. Это связано с тем, что без этой проверки каждый раз, когда поле очищается, приложение жалуется, что значение не является числовым.

Я был бы рад получить помощь в устранении этой проблемы!


person Meaulnes    schedule 29.10.2020    source источник


Ответы (1)


Похоже, что wire: model.lazy обязательно. В первой группе я использовал его в другое время, не осознавая этого. Так что лень в этом случае обязательна.

person Meaulnes    schedule 29.10.2020