【问题标题】:Blazor select bind to a value in a list [duplicate]Blazor 选择绑定到列表中的值 [重复]
【发布时间】:2020-02-14 20:15:51
【问题描述】:

我能够将 int 类型(这是 SelectedDiagnosisIdList 列表的第一个元素)变量绑定到 html 选择的选定元素:

<div>
    <label>Diagnosis:</label>
    <div>
        <select @bind="@userInfo.SelectedDiagnosisIdList[0]">
            @foreach (var item in diagnoses)
            {
                <option value="@item.Id">@item.Name</option>
            }
        </select>
        <p>@userInfo.SelectedDiagnosisIdList[0]"</p>
    </div>
</div>

@code
{
    List<int> SelectedDiagnosisIdList = new List<int>() { 0 };
    List<Diagnosis> diagnoses; //  populated from db in OnInitializedAsync

}

这很好用,当我更改 UI 上的选定值时,段落的值会发生变化。


现在,我想添加更多的Diagnoses,所以我试图维护更多的s,并在SelectedDiagnosisIdList中添加更多的元素:

<div>
    <label>Diagnosis:</label>
    <div>
        @for(int i = 0; i < userInfo.SelectedDiagnosisIdList.Count; i++)
            <select @bind="@userInfo.SelectedDiagnosisIdList[i]">
                @foreach (var item in diagnoses)
                {
                    <option value="@item.Id">@item.Name</option>
                }
            </select>
            <p>@userInfo.SelectedDiagnosisIdList[i]</p>
        }
    </div>
</div>

@code
{
    List<int> SelectedDiagnosisIdList = new List<int>() { 0 };
    List<Diagnosis> diagnoses; //  populated from db in OnInitializedAsync

}

这会破坏程序,当我选择一个项目和控制台时,UI 上没有任何反应:

blazor.webassembly.js:1 WASM: Unhandled exception rendering component:
blazor.webassembly.js:1 WASM: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
WASM: Parameter name: index
blazor.webassembly.js:1 WASM:   at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&)
blazor.webassembly.js:1 WASM:   at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) <0x20c1360 + 0x000ce> in <71c4fd446b1842ba93fd332e5f4f9c06>:0 
blazor.webassembly.js:1 WASM: --- End of stack trace from previous location where exception was thrown ---
blazor.webassembly.js:1 WASM:   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion (System.Threading.Tasks.Task task) <0x269de40 + 0x000e6> in <cbf249d7f04d4fa18d15bfae8ef7f389>:0 
WASM:   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask (System.Threading.Tasks.Task taskToHandle) <0x269e988 + 0x000c2> in <cbf249d7f04d4fa18d15bfae8ef7f389>:0 

我不明白问题出在哪里,我怎样才能让它工作......请帮助

【问题讨论】:

    标签: c# asp.net-core blazor webassembly


    【解决方案1】:

    我猜您的问题与 for 循环有关。您应该在循环中定义一个局部变量,如下所示:

        <div>
        @for(int i = 0; i < userInfo.SelectedDiagnosisIdList.Count; i++)
          {
            int local = i;
            <select id=$"dropdown{local+1}" 
                   @bind="@userInfo.SelectedDiagnosisIdList[local]">
                @foreach (var item in diagnoses)
                {
                    <option value="@item.Id">@item.Name</option>
                }
            </select>
            <p>@userInfo.SelectedDiagnosisIdList[local]</p>
        }
        </div>
    

    希望这会有所帮助...

    【讨论】:

    • 太棒了,它成功了 :) 你能解释一下它为什么有效吗?
    • 当您使用不带局部变量的 for 循环时,运行时会访问包含循环末尾值的 i 变量。但是当您使用局部变量时,在循环的每次迭代中都会创建一个新变量来存储新值,因此当运行时访问变量时,每个变量都包含不同的值。
    • 您可以在此处阅读有关此问题的更多信息:csharpindepth.com/Articles/Closures
    • 主要是因为渲染是异步的,所以for循环是在一个lambda里面执行的,局部变量把变量引入到lambda里面。您还需要另一件事来使代码也正常工作。实际选择元素 EG 上的 HTML Id 属性:id="dropdown1"、id="dropdown2" 等等,以便封闭的表单在进行选择时知道哪个下拉列表。
    • 没错,我必须使用 HTML Id 才能让它工作。
    猜你喜欢
    • 1970-01-01
    • 2020-02-17
    • 2021-07-23
    • 1970-01-01
    • 2018-05-11
    • 2023-03-06
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多