You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 09:22:31