accessor - 使用 mutators 和 accessor 时的 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>
如您所见,第一个输入使用数字类型,而第二个输入使用文本类型。这只是为了解释,因为无论是数字输入类型还是文本输入类型,问题都是一样的。但现在让我说一下问题所在。
有什么问题? 问题在于,对于第二个字段设备。您可以删除所有输入的数字,但第一个数字除外。不过,如果您使用左箭头键将光标放在字段的开头,您可以输入一个新值,然后删除最后一个字符,但不要让字段为空。这对用户来说相当烦人。
我必须补充一点,如果不使用修改器和访问器,则不存在此行为。此外,boiler_volume的第一个字段即使使用访问器和修改器也能正常工作。最后也是最后,所有其他字段的行为相同,即错误。
注意 线
protected $appends=...
不会改变任何东西。
其他奇怪 的行为 查看 mutators 和 accessors,您可以看到一些检查该值是否为数字而不是 null。这是因为如果没有此检查,每次清空字段时,应用程序都会抱怨该值不是数字。
我很乐意得到一些帮助来解决这个问题!
解决方案
似乎 wire:model.lazy 是强制性的。在第一组中,我在另一个时间使用它而没有意识到它。因此,在这种情况下,懒惰是强制性的。
推荐阅读
- react-native - 世博会开始找不到模块'hoek'
- php - 在 Laravel 中覆盖路由名称
- c# - Dictionary.ContainsKey() 是否比 FirstOrDefault() 更好?
- asynchronous - 如何优雅地关闭 Tokio 运行时以响应 SIGTERM?
- javascript - 是否可以从谷歌应用程序脚本中的库调用容器绑定脚本函数?
- android-studio - 在 imageView 上捕获并显示图像,现在我想将 imageView 传递给另一个活动
- html - 页面的侧滚动条覆盖页面内容
- c - OpenMP Monte_Carlo 模拟实现目标接近 PI
- python - 从数据库中下载 django 中的文件,并在其中查看 pdf 文件
- javascript - 为什么图片没有显示在 JavaScript Toggle 中?