我有一个Livewire组件,这是一个产品过滤器。这些查询都运行良好,但有时会产生无限的请求循环。
你可以在下面的GIF中看到这种情况,这是Laravel Debugbar的捕获。我单击了一些过滤器,然后突然它进入了这个请求循环。
我特别使用wire:loading.attr=禁用
在视图中的过滤器上,所以当请求仍在处理时,某人不能选择过滤器。
我的代码和一些背景:
Livewire组件
use App\Models\Product;
use App\Models\Brand;
use App\Models\Color;
class SearchProducts extends Component
{
public ?array $brand = [];
public ?array $color = [];
protected $queryString = ['brand', 'color'];
public function render()
{
$products = Product::query();
$products = $products->with('brand');
$products = $products->with('colors');
$products = $this->filterBrands($products);
$products = $this->filterColors($products);
$products = $products->paginate(24);
return view('livewire.search-products', [
'all_brands' => Brand::where('status', 'active')->get(),
'all_colors' => Color::where('status', 'active')->get(),
])->extends('app');
}
public function filterBrands($query)
{
$queryFilterBrand = array_filter($this->brand);
return empty($queryFilterBrand) ? $query : $query->whereIn('brand_id', $queryFilterBrand);
}
public function filterColors($query)
{
$queryFilterColor = array_filter($this->color);
return empty($queryFilterColor) ? $query : $query->whereHas('colors', function ($q) use ($queryFilterColor) {
$q->whereIn('color_id', $queryFilterColor);
});
}
}
我使用array\u filter
的原因是,如果我取消选择颜色值并在键中使用字符(wire:model=“brand.b{$brand-
Livewire的观点和问题
这很好:
@foreach($all_brands as $brand)
<input type="checkbox" value="{{ $brand->id }}" id="brand.{{ $brand->id }}" wire:model="brand.{{ $brand->id }}" wire:loading.attr="disabled">
<label class="search-label search-wide-label mb-2" for="brand.{{ $brand->id }}">{{ $brand->title }} <i class="fal fa-times float-right selected-icon"></i></label>
@endforeach
但当我选择两种或更多颜色之后,或者选择一种颜色然后取消选择时,这会创建一个无限循环。因此,问题似乎发生在第二次交互之后:
@foreach($all_colors as $color)
<input type="checkbox" value="{{ $color->id }}" id="color.{{ $color->id }}" wire:model="color.{{ $color->id }}" wire:loading.attr="disabled">
<label class="search-label search-wide-label mb-2" for="color.{{ $color->id }}">{{ $color->title }} <i class="fal fa-times float-right selected-icon"></i></label>
@endforeach
这很奇怪,因为这个边栏选项卡片段与上面所示的$brand
完全相同:
唯一不同的是,颜色
关系是与
品牌
之间的关系。
我现在想这就是问题所在。。。
我尝试过但没有成功的事情
$all_colors
的@foreach
循环,只需将过滤器放入纯HTML(以检查问题是否与循环相关)wire:key=“brand.{{$brand-
控制台错误
最后一点,只有当无限循环发生时,我才在控制台中得到这个错误,所以它很可能是因果关系。
TypeError:null不是对象(计算'directive.value.split')
未处理的promise拒绝:TypeError:null不是对象(计算'directive.value.split')
都在加载状态中。js
,我认为这是一个Livewire Javascript文件。
错误似乎发生在这里:
function startLoading(els) {
els.forEach(({ el, directive }) => {
if (directive.modifiers.includes('class')) {
let classes = directive.value.split(' ').filter(Boolean)
回答了GitHub问题,复制到这里让其他人能够找到。
这是一个变形问题。
触发错误和循环的代码是wire:加载标题行和产品行。
原因是,当您选择两种或多种颜色时,不会显示结果。接下来发生的是,您将从显示标题/产品/总计切换到显示空状态。
但默认情况下,mordom并不知道应该删除旧div并添加新div。取而代之的是,它正试图将旧的第一个部门“改造”成新的部门。这意味着线:加载监听器在不应该被注册的时候仍然被注册。因此,为什么错误和循环。
不过,这是一个简单的解决方案。您需要将线键添加到定义它们的div中,以便morphdom知道它们实际上已完全更改,并删除旧键并添加新键。
看看下面的差异截图,了解我是如何让它工作的。我为这个文件中的所有顶级div添加了一个线键。
无论何时,我们都建议使用这样的条件来为条件中处于第一级的任何元素添加wire: key,这样变形就知道发生了变化。VueJS也有同样的问题,在循环中需要密钥。
diff的截图
因此,如果您在像这样的Foreach
循环中使用wire: Model
,您必须这样写:wire: Model="brand。{{$brand-
最新消息
无限循环由此解决,但现在发生的是,一旦选中复选框并再次单击以取消选中,数组值将设置为零,而不是从数组中删除。因此,其中
将查找值为0的品牌ID,该ID不会返回结果。
更新2
循环实际上没有解决。。。见原问题。因为浪费了太多的时间和咖啡,所以给了这个$%$奖金。
我看到了几个问题:
您的
此外,您在输入元素上使用相同的name
。这将导致复选框的问题,因为传递到后端的值具有相同的名称,我相信livewire将尝试基于此进行同步。将输入中的name
字段更改为唯一可能是答案。