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

如何在Blazor Razor组件的foreach循环中获取动态Textarea值

解决Blazor中动态生成Textarea的独立值绑定问题

你的核心问题是所有Textarea都绑定到了同一个变量,导致输入值互相覆盖,没法区分每个问题对应的答案。我来帮你一步步修复这个问题:

1. 调整数据模型结构

首先需要修改userans模型,让它能存储多个问题的答案,而不是单个值。建议新增一个专门的类来保存单条问题的答案,再用列表来存储所有答案:

// 新增的答案项类,关联问题ID和对应答案
public class QuestionAnswer
{
    // 替换为你实际的问题唯一标识字段
    public int QuestionId { get; set; }
    // 存储当前问题的输入答案
    public string AnswerContent { get; set; } = string.Empty;
}

// 修改你的userans模型,添加答案列表属性
public class UserAnswersModel
{
    public List<QuestionAnswer> Answers { get; set; } = new List<QuestionAnswer>();
    // 其他原有属性...
}

2. 初始化答案列表

在加载完Questiontable数据后,需要初始化答案列表,确保每条问题都对应一个空的答案项:

protected override async Task OnInitializedAsync()
{
    // 执行原有的Questiontable数据加载逻辑
    // ...

    // 初始化答案列表,与问题数量一一对应
    if (Questiontable != null && Questiontable[0].Questiondata.Any())
    {
        userans.Answers = Questiontable[0].Questiondata
            .Select(q => new QuestionAnswer { QuestionId = q.Id }) // 替换q.Id为你实际的问题ID字段
            .ToList();
    }
}

3. 修改Razor组件的绑定逻辑

注意:不要直接用foreach循环绑定集合项,Blazor的闭包特性会导致所有绑定都指向最后一个循环项。推荐用以下两种方式:

方式一:使用@for循环(推荐,避免闭包问题)

<EditForm Model="@userans" OnValidSubmit="@oninput">
    <DataAnnotationsValidator />
    <h3>Test </h3>
    @if (Questiontable == null)
    {
        <p><em>Loading...</em></p>
    }
    else
    {
        <table class="table">
            <thead>
                <tr></tr>
            </thead>
            <tbody>
                @for (int i = 0; i < Questiontable[0].Questiondata.Count; i++)
                {
                    // 必须捕获当前索引,避免闭包问题
                    var currentIndex = i;
                    var currentQuestion = Questiontable[0].Questiondata[currentIndex];
                    <tr>
                        <td>@currentQuestion.Question</td>
                    </tr>
                    <tr>
                        <th>
                            <textarea rows="2" cols="20" 
                                      @bind="@userans.Answers[currentIndex].AnswerContent"
                                      @bind:Event="oninput"></textarea>
                        </th>
                    </tr>
                }
            </tbody>
        </table>
        <div align="center">
            <button class="btn btn-primary" type="submit" @onclick="btnnextclick">Next</button>
        </div>
    }
</EditForm>

方式二:使用配对遍历(如果习惯foreach)

如果你更想用foreach,可以用Zip方法把问题和答案项配对,确保一一对应:

<tbody>
    @foreach (var itemPair in Questiontable[0].Questiondata.Zip(userans.Answers, (q, a) => new { Question = q, Answer = a }))
    {
        <tr>
            <td>@itemPair.Question.Question</td>
        </tr>
        <tr>
            <th>
                <textarea rows="2" cols="20" @bind="@itemPair.Answer.AnswerContent"></textarea>
            </th>
        </tr>
    }
</tbody>

4. 获取所有输入值

现在在你的提交方法里,就能遍历userans.Answers拿到每条问题对应的答案了:

private void oninput()
{
    foreach (var answerItem in userans.Answers)
    {
        // 这里可以处理每个答案,比如保存到数据库
        Console.WriteLine($"问题ID {answerItem.QuestionId} 的答案:{answerItem.AnswerContent}");
    }
    // 也可以直接把整个Answers列表传给后端处理
}

关键注意事项

  • 确保你的问题模型有唯一的ID字段,这样后续能准确关联问题和答案
  • 初始化答案列表时,要保证问题数量和答案项数量完全一致
  • 用@for循环时必须捕获当前索引变量(var currentIndex = i),否则会出现所有绑定指向最后一项的问题

内容的提问来源于stack exchange,提问作者Ashwani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:10:18