Как связать элемент из коллекции / списка в Blazor? - PullRequest
2 голосов
/ 26 февраля 2020

Я хочу привязать значения к элементам из моего списка в al oop, но не могу найти хорошее решение.

<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>

Когда я пытаюсь привязать-Value к элементу из списка, я получение ошибки:

  1. ошибка CS0131: в левой части назначения должна быть ошибка переменной, свойства или индексатора
  2. ошибка CS1662: невозможно преобразовать лямбда-выражение в предназначенный тип делегата потому что некоторые из возвращаемых типов в блоке неявно конвертируются в возвращаемый делегатом тип

Интересно, есть ли какой-нибудь возможный способ привязать данные к коллекции? Мне это нужно, потому что моя модель имеет свойство типа List. В моей форме ввода я хочу разрешить добавлять столько строк, сколько потребуется пользователю.

edit:

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

Я также попытался сделать это в foreach l oop, но появляется другая ошибка: невозможно присвоить «эффекту», так как это «итерационная переменная foreach

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>
            }

1 Ответ

0 голосов
/ 28 апреля 2020

Привязка не может работать: когда изменяется значение входного текста, вы хотите изменить список, а не сам элемент.

Вместо этого вам нужно «разделить» то, что делает привязка в двух. направления:

  • установить значение поля ввода на основе значения модели
  • установить модель при изменении значения поля ввода

Приведенный ниже код показывает, как решить основную проблему, затем вам необходимо адаптировать ее к вашим потребностям.

@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, которое должно знать, где в исходном списке должно быть обновлено значение.

Если вы предпочитаете, вы можете использовать для l oop:

@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" };

}
...