如何绑定Blazor中集合

如何绑定Blazor中集合

本文介绍了如何绑定Blazor中集合/列表中的元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在循环中将值绑定到列表中的元素,但找不到合适的解决方案.

I want to bind values to elements from my list in a loop but I cannot find the good solution.

<EditForm Model="@dailyReport" OnValidSubmit="@SubmitDailyReport">
        <p>
            <label>Count: </label>
            <InputNumber min="1" id="numberOfEffects" @bind-Value="numberOfEffects" />
        </p>
        @{
            for (int i = 1; i <= numberOfEffects; i++)
            {
                if (effects.Count < i)
                {
                    effects.Add("");
                }

                if (effects.Count > i)
                {
                    effects.RemoveAt(effects.Count - 1);
                }

                string concatId = "effect" + i.ToString();

                <p>
                    <label for="@concatId">@i</label>
                    <InputText id="@concatId" @bind-Value="effects.ElementAt(i-1)" />
                </p>
            }
         }
//rest code
 </EditForm>

当我尝试将值绑定到列表中的元素时,出现错误:

When I am trying to bind-Value to element from a list I am getting an error:

  1. 错误CS0131:作业的左侧必须为变量,属性或索引器错误
  2. 错误CS1662:无法转换lambda表达式为预期的委托类型,因为某些返回块中的类型不能隐式转换为委托返回类型

我想知道是否有任何可能的方法将数据绑定到集合.我需要它,因为我的模型具有类型为List的属性.在我的输入表单中,我希望允许添加用户所需的任意多个字符串.

I wonder if there is any possible way to bind data to collection. I need it because my Model has a property of type List. In my input form I want to allow adding as many strings as will be needed by the user.

@code
{
    private DailyReport dailyReport = new DailyReport();
    private List<string> effects = new List<string>();
}

我也尝试在foreach循环中执行此操作,但显示另一个错误:无法分配给效果",因为它是"foreach迭代变量"

I also tried to do it in foreach loop but another error is showed:Cannot assign to 'effect' because it is a 'foreach iteration variable

foreach (var effect in effects)
            {
                index++;
                Console.WriteLine(index);

                string concatId = "effect" + index.ToString();

                <p>
                    <label for="@concatId">@index</label>
                    <InputText id="@concatId" @bind-Value="effect" />
                </p>
            }

推荐答案

绑定不起作用:当输入文本的值更改时,您要修改列表,而不是元素本身.

The binding cannot work: when the value of an input text changes, you want to modify the list, not the element itself.

相反,您必须在两个方向上拆分"绑定的作用:

Instead, you have to "split" what the binding does in the two directions:

  • 根据模型的值设置输入字段的值
  • 在输入字段的值更改时设置模型

下面的代码显示了如何解决主要问题,然后必须根据需要进行调整.

The code below shows how to solve the main problem, then you have to adapt it to your needs.

@foreach (var element in effects.Select((e, i) => new { Effect = e, Index = i}))
{
    <p>
        <label for="@($"effect{element.Index}")">@element.Index</label>
        <input id="@($"effect{element.Index}")" value="@element.Effect"
               @onchange="@(e => effects[element.Index] = e.Value.ToString())" />
    </p>
}

@code {

    private List<string> effects = new List<string>() { "a", "b", "c" };

}

第一行达到了目的:将列表转换为可枚举的列表,其中每个元素都是一个新对象,该对象封装了 effects 列表中的索引和值.您需要索引主要是因为 @onchange 事件,该事件必须知道应在原始列表中的哪个位置更新值.

The first line does the trick: it converts the list to an enumerable in which each element is a new object that encapsulates both the index in the effects list and the value. You need the index mainly because of the @onchange event, which must know where in the original list the value should be updated.

如果您愿意,可以使用for循环:

If you prefer you can use a for loop:

@for (int i = 0; i < effects.Count; i++)
{
    // see https://stackoverflow.com/a/56426146/323447
    var iCopy = i;

    <p>
        <label for="@($"effect{i}")">@i</label>
        <input id="@($"effect{i}")" value="@effects[i]"
               @onchange="@(e => effects[iCopy] = e.Value.ToString())" />
    </p>
}

@code {

    private List<string> effects = new List<string>() { "a", "b", "c" };

}

这篇关于如何绑定Blazor中集合/列表中的元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 23:02