Livewire动态下拉问题:新增行Sub Commodity依赖首行Commodity
问题描述
我用Livewire实现了表单行的增删和动态下拉框功能,但现在存在一个问题:新增行的Sub Commodity下拉框选项仅依据首行选中的Commodity生成,而非当前行自身选中的Commodity对应的选项。测试显示,若首行未选择Commodity,即使新增行选中了Commodity,其Sub Commodity下拉框也无任何选项。
e-linkage-components.blade.php
<div class="row"> <div class="col-md-4 mb-2"> <label for="associationName" class="form-label label-style">Association Name</label> <input wire:model="associationName.0" type="text" class="form-control" name="associationName[]" id="associationName" autocomplete="off" value="{{ $associationProfile->association }}" readonly> </div> <div class="col-md-4 mb-2"> <label for="commodity" class="form-label label-style">Commodity</label> <select wire:model.live="commoditiesID.0" id="commodity" name="commodity[]" class="form-select"> <option value="">Select Commodity</option> @foreach ($commodities as $commodity) <option value="{{ $commodity->id }}">{{ $commodity->commodity }}</option> @endforeach </select> </div> <div class="col-md-4 mb-2"> <label for="subCommodity" class="form-label label-style">Sub Commodity</label> <select wire:model.live="subCommoditiesID.0" id="subCommodity" name="subCommodity[]" class="form-select"> <option value="">Select Sub Commodity</option> @foreach ($subCommodities as $subCommodity) <option value="{{ $subCommodity->id }}">{{ $subCommodity->subCommodities }}</option> @endforeach </select> </div> <div class="row"> <div class="col-md-2 mb-2"> <label for="variety" class="form-label label-style">Variety</label> <input wire:model="variety.0" type="text" class="form-control" name="variety[]" id="variety" autocomplete="off"> </div> <div class="col-md-2 mb-2"> <label for="volume" class="form-label label-style">Volume (Kg)</label> <input wire:model="volume.0" type="text" class="form-control" name="volume[]" id="volume" autocomplete="off"> </div> </div> <div class="row"> <div class="col-md-3 mb-2"> <label for="startDate" class="form-label label-style">Estimated Time of Harvest <br> (Start Date)</label> <input wire:model="startDate.0" type="date" class="form-control" name="startDate[]" id="startDate"> </div> <div class="col-md-3 mb-2"> <label for="endDate" class="form-label label-style">Estimated Time of Harvest <br> (End Date)</label> <input wire:model="endDate.0" type="Date" class="form-control" name="endDate[]" id="endDate"> </div> </div> <hr> @foreach ($inputs as $key => $value) <div class="col-md-4 mb-2"> <label for="associationName" class="form-label label-style">Association Name</label> <input wire:model="associationName.{{ $value }}" type="text" class="form-control" name="associationName[]" id="associationName" autocomplete="off" value="{{ $associationProfile->association }}" readonly> </div> <div class="col-md-4 mb-2"> <label for="commodity" class="form-label label-style">Commodity</label> <select wire:model="commoditiesID.{{ $value }}" id="commodity" name="commodity[]" class="form-select"> <option value="">Select Commodity</option> @foreach ($commodities as $commodity) <option value="{{ $commodity->id }}">{{ $commodity->commodity }}</option> @endforeach </select> </div> <div class="col-md-4 mb-2"> <label for="subCommodity" class="form-label label-style">Sub Commodity</label> <select wire:model="subCommoditiesID.{{ $value }}" id="subCommodity" name="subCommodity[]" class="form-select"> <option value="">Select Sub Commodity</option> @foreach ($subCommodities as $subCommodity) <option value="{{ $subCommodity->id }}">{{ $subCommodity->subCommodities }}</option> @endforeach </select> </div> <div class="row"> <div class="col-md-2 mb-2"> <label for="variety" class="form-label label-style">Variety</label> <input wire:model="variety.{{ $value }}" type="text" class="form-control" name="variety[]" id="variety" autocomplete="off"> </div> <div class="col-md-2 mb-2"> <label for="volume" class="form-label label-style">Volume (Kg)</label> <input wire:model="volume.{{ $value }}" type="text" class="form-control" name="volume[]" id="volume" autocomplete="off"> </div> </div> <div class="row"> <div class="col-md-3 mb-2"> <label for="startDate" class="form-label label-style">Estimated Time of Harvest <br> (Start Date)</label> <input wire:model="startDate.{{ $value }}" type="date" class="form-control" name="startDate[]" id="startDate"> </div> <div class="col-md-3 mb-2"> <label for="endDate" class="form-label label-style">Estimated Time of Harvest <br> (End Date)</label> <input wire:model="endDate.{{ $value }}" type="Date" class="form-control" name="endDate[]" id="endDate"> </div> <div class="col-md-2 mb-2 d-flex mt-auto"> <button type="button" wire:click="remove({{ $key }})" class="btn btn-danger">Remove</button> </div> </div> <hr> @endforeach <div class="col-md-2 mb-2 d-flex mt-auto"> <button type="button" wire:click="add({{ $i }})" class="btn btn-success">Add more</button> </div> </div>
ELinkageComponents.php
<?php namespace App\Livewire; use App\Models\AssociationProfile; use App\Models\BuyerLinkage; use App\Models\Commodities; use App\Models\SubCommodities; use Illuminate\Support\Facades\Auth; use Livewire\Component; class ELinkageComponents extends Component { public $user; public $associationProfile; public $ELinkages; public $commoditiesID; public $subCommoditiesID; public $inputs; public $i; public $associationName; public $variety; public $volume; public $startDate; public $endDate; public function mount() { $this->user = Auth::user(); $this->associationProfile = AssociationProfile::where('userId', $this->user->id)->first(); $this->ELinkages = BuyerLinkage::join('commodities', 'buyer_e_linkages.commodity', '=', 'commodities.id')->select('buyer_e_linkages.*', 'commodities.commodity as commodity_name')->get(); $this->inputs = []; $this->commoditiesID = []; $this->subCommoditiesID = []; $this->associationName = [$this->associationProfile->association]; $this->variety = []; $this->volume = []; $this->startDate = []; $this->endDate = []; $this->i = 1; } public function add($i) { $this->i = $i + 1; array_push($this->inputs, $i); $this->associationName[$i] = $this->associationProfile->association; } public function remove($key) { unset($this->inputs[$key]); } public function render() { return view('livewire.e-linkage-components', [ 'commodities' => Commodities::all(), 'subCommodities' => SubCommodities::where('commodityId', $this->commoditiesID)->get(), 'user' => $this->user, 'associationProfile' => $this->associationProfile, 'ELinkages' => $this->ELinkages, ]); } }
解决方案
问题核心是当前用了全局的subCommodities集合,所有行共享同一组子商品数据,没有区分每行的Commodity选择。要实现每行Sub Commodity独立关联,需按以下步骤修改:
1. 后端组件修改
1.1 新增每行子商品存储属性
在ELinkageComponents.php中添加$rowSubCommodities,用于单独存储每行对应的子商品:
public $rowSubCommodities = [];
1.2 移除全局子商品查询,添加行级监听方法
删除render方法中全局的subCommodities查询,新增监听Commodity变化的方法,实时加载对应行的子商品:
public function updatedCommoditiesID($value, $rowIndex) { if ($value) { $this->rowSubCommodities[$rowIndex] = SubCommodities::where('commodityId', $value)->get(); } else { $this->rowSubCommodities[$rowIndex] = collect(); } // 清空当前行的子商品选中状态 unset($this->subCommoditiesID[$rowIndex]); } public function render() { return view('livewire.e-linkage-components', [ 'commodities' => Commodities::all(), 'user' => $this->user, 'associationProfile' => $this->associationProfile, 'ELinkages' => $this->ELinkages, ]); }
1.3 初始化首行子商品集合(可选)
若需要首行默认空集合,在mount方法中添加:
public function mount() { // ... 原有代码 $this->rowSubCommodities[0] = collect(); }
2. 前端视图修改
2.1 首行Sub Commodity下拉框调整
将首行的子商品循环改为使用对应行的集合:
<select wire:model.live="subCommoditiesID.0" id="subCommodity" name="subCommodity[]" class="form-select"> <option value="">Select Sub Commodity</option> @foreach ($rowSubCommodities[0] ?? [] as $subCommodity) <option value="{{ $subCommodity->id }}">{{ $subCommodity->subCommodities }}</option> @endforeach </select>
2.2 循环生成行的调整
- 给循环内的Commodity选择器添加
wire:model.live,确保实时触发更新:
<select wire:model.live="commoditiesID.{{ $value }}" id="commodity" name="commodity[]" class="form-select">
- 修改Sub Commodity循环,使用当前行的子商品集合:
<select wire:model="subCommoditiesID.{{ $value }}" id="subCommodity" name="subCommodity[]" class="form-select"> <option value="">Select Sub Commodity</option> @foreach ($rowSubCommodities[$value] ?? [] as $subCommodity) <option value="{{ $subCommodity->id }}">{{ $subCommodity->subCommodities }}</option> @endforeach </select>
内容的提问来源于stack exchange,提问作者Jave
相关产品推荐
相关产品推荐

