Создать динамический список / чекбокс и лабель взаимосвязанны между собой /

написав следующий код

@foreach (var item in Items)
{
    <div class="listSelector">
        @if (RowTemplate is not null)
        {
            <input type="checkbox" id="listId[intList]" name="item[intList]" value="listId[intList]" />
            <label for="listId[intList]">@RowTemplate(item)</label>
        }
    </div>

    intList++;

    var test = intList;
}

<style>
    .listSelector {
        display: flex;
        flex-direction: column;
    }
</style>

@code
{
    public int intList { get; set; } = 0;
}

Я получаю список, название и рядом чекбокс

...только вот когда я нажимаю на лабель чтоб чекбокс подтвердить, происходит иногда сбой, поясню... через раз срабатывает, то он ставит галочку не на тот чекбокс то на нужный, я подумала, что если добавить какой то еще символ, чтоб каждый "пункт" списка был уникальным, добавила им переменную intList она меняет значение, только вот по моему это не очень исправило ситуацию и как то вообще коряво выглядит.

Вопрос: Как можно создать такой "пункт" для списка, чтоб он был "динамическим" (чекбокс и лабель в каждом пункте) Множественный выбор из списка ?


Ответы (1 шт):

Автор решения: Dev18

Для решения вашей проблемы с динамическим списком чекбоксов и меток в Blazor рекомендуется использовать директиву @bind, чтобы связать состояние чекбокса с моделью данных. Что позволит автоматически обновлять состояние модели при взаимодействии с пользовательским интерфейсом.

Ниже приведен пример, который демонстрирует использование @bind для связи состояния чекбоксов с моделью CheckboxItem. В этом примере также добавлена функция OnSubmit, и на скриншоте выбранные эллементы

введите сюда описание изображения

@page "/checkbox-list"

@foreach (var item in Items.Select((value, index) => new { value, index }))
{
    <div class="listSelector">
        <input type="checkbox" id="[email protected]" 
               @bind="@item.value.IsChecked" />
        <label for="[email protected]">@item.value.Name</label>
    </div>
}

<button @onclick="OnSubmit">Submit</button>

<style>
    .listSelector {
        display: flex;
        flex-direction: column;
        margin-bottom: 8px; 
    }
</style>

@code {
    public List<CheckboxItem> Items { get; set; } = new List<CheckboxItem>
    {
        new CheckboxItem { Name = "Item 1", IsChecked = false },
        new CheckboxItem { Name = "Item 2", IsChecked = false },
        new CheckboxItem { Name = "Item 3", IsChecked = false }
    };

    private void OnSubmit()
    {
        var selectedItems = Items
                            .Where(item => item.IsChecked)
                            .Select(item => item.Name)
                            .ToList();
    }

    public class CheckboxItem
    {
        public string Name { get; set; }
        public bool IsChecked { get; set; }
    }
}

Переиспользование компонента с RenderFragment

Если вы хотите использовать этот функционал в разных частях вашего проекта, не дублируя код, можно создать компонент и использовать RenderFragment для передачи шаблона. Это позволяет гибко определять, как каждый элемент списка должен отображаться.

razorPage

@page "/example"

@using MyProjectNameSpace.Data

<CheckboxListComponent TItem="string" Items="@items" RowTemplate="RenderTemplate" />

@code {
    private List<CheckboxItem<string>> items = new List<CheckboxItem<string>>
    {
        new CheckboxItem<string> { Item = "Item 1", IsChecked = false },
        new CheckboxItem<string> { Item = "Item 2", IsChecked = false },
        new CheckboxItem<string> { Item = "Item 3", IsChecked = false }
    };

    private RenderFragment<string> RenderTemplate => (item) => @<span>@item</span>;
}

component CheckboxListComponent

@using MyProjectNameSpace.Data
@typeparam TItem

@foreach (var item in Items.Select((value, index) => new { value, index }))
{
    <div class="listSelector">
        <input type="checkbox" id="[email protected]" 
               @bind="@item.value.IsChecked" />
        <label for="[email protected]">
            @RowTemplate(item.value.Item)
        </label>
    </div>
}

<button @onclick="OnSubmit">Submit</button>

<style>
    .listSelector {
        display: flex;
        flex-direction: column;
        margin-bottom: 8px; 
    }
</style>

@code {
    [Parameter] public List<CheckboxItem<TItem>> Items { get; set; } 
    = new List<CheckboxItem<TItem>>();
    [Parameter] public RenderFragment<TItem> RowTemplate { get; set; }  
    // RenderFragment<TItem> как параметр

    private void OnSubmit()
    {
        var selectedItems = Items
                            .Where(item => item.IsChecked)
                            .Select(item => item.Item)
                            .ToList();
    }
}

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

→ Ссылка