Blazor .NET 8 — InputSelect: создание раскрывающегося списка из моделей

Я только что прошел курс по Blazor .NET 8 от iamtimcorey.com.

Я хочу создать раскрывающуюся форму, используя опцию InputSelect из собственной формы. Но я не могу понять, как заполнить раскрывающийся список, используя столбец из моей модели, полученный из моей базы данных SQL. В примере на курсе был настраиваемый список, и я не могу заполнить пробелы из-за своих ограниченных знаний.

Я хочу использовать данные из этой модели:

Модели

У меня есть две хранимые процедуры для взаимодействия с базой данных. Один из них получает все данные.

Другой получает только два столбца: отдельные NoFacture (чтобы эти числа не повторялись в раскрывающемся списке) и связанный с ним клиент NoFacture (NoFacture означает номер счета).

Хранимые процедуры, вызываемые из приложения Blazor

Результат хранимой процедуры

Я хочу перечислить все NoFacture в раскрывающемся списке, используя метод GetCommandesToShip().

На моем компоненте/странице Razor я инициализировал пустую модель, которую хочу заполнить выбранным NoFacture. Но я не могу заполнить InputSelect своими данными.

Смотрите этот скриншот:

Тест создания раскрывающегося списка с помощью Inputselect

Я знаю, что есть способ использовать объекты, но у меня нет примера, и я не могу его понять.

Вот мой код из приложения Blazor:

<h1>Expédition / Scanner</h1>

@if (CommandesDetails == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <EditForm Enhance Model = "CommandeNoForm" method = "post" FormName = "noCommandeInput" OnSubmit = "SubmitNoCommande">
        <div>
            <br/>
            <label>No de Commande</label>
            <br/>
            <InputSelect @bind-Value = "@CommandesNoForm.NoFacture">
                @foreach (var comm in Enum.GetValues(Commandes.NoFacture))
                {
                    <option value = "@comm">@comm.ToString()</option>
                }
            </InputSelect>
        </div>
    </EditForm>

}

@code {

    [SupplyParameterFromForm]
    private CommandesDetailsModel CommandeNoForm { get; set; } = new();
    private void SubmitNoCommande()
    {
    }

    private IEnumerable<CommandesDetailsModel>? Commandes;
    private IEnumerable<CommandesDetailsModel>? CommandesDetails;

    protected override async Task OnInitializedAsync()
    {
        Commandes = await AcombaSql.GetCommandesToShip();
        CommandesDetails = await AcombaSql.GetCommandesDetailsToShip();
    }
}
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
0
54
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Сначала специальный компонент на основе InputSelect:

БлазрИнпутселект

@*
/// ============================================================
/// Author: Shaun Curtis, Cold Elm Coders
/// License: Use And Donate
/// If you use it, donate something to a charity somewhere
/// ============================================================
*@

@using System.Linq.Expressions
@typeparam TValue
@typeparam TListItem

<InputSelect @attributes=AdditionalAttributes
             TValue = "TValue"
             Value=this.Value
             ValueChanged=this.OnChange
             ValueExpression=this.ValueExpression>

    @if (this.Value is null)
    {
        <option selected disabled>@this.PlaceholderText</option>
    }

    @foreach (var option in this.DisplayOptionsItems)
    {
        <option value = "@(this.OptionValueDelegate(option))">@(this.OptionTextDelegate(option))</option>
    }

</InputSelect>

@code {
    [Parameter] public TValue? Value { get; set; }
    [Parameter] public EventCallback<TValue?> ValueChanged { get; set; }
    [Parameter] public Expression<Func<TValue>>? ValueExpression { get; set; }

    [Parameter, EditorRequired] public IEnumerable<TListItem> DisplayOptionsItems { get; set; } = default!;
    [Parameter, EditorRequired] public Func<TListItem, string> OptionValueDelegate { get; set; } = default!;
    [Parameter, EditorRequired] public Func<TListItem, string> OptionTextDelegate { get; set; } = default!;

    [Parameter] public string PlaceholderText { get; set; } = " -- Select an Option -- ";
    [Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary<string, object>? AdditionalAttributes { get; set; }

    protected override void OnInitialized()
    {
        // Check we have a Options list if not throw an exception before we try and render a null list
        ArgumentNullException.ThrowIfNull(this.DisplayOptionsItems);
        ArgumentNullException.ThrowIfNull(this.OptionValueDelegate);
        ArgumentNullException.ThrowIfNull(this.OptionTextDelegate);
    }

    private Task OnChange(TValue value)
        => this.ValueChanged.InvokeAsync(value);
}

А затем демонстрационная страница, демонстрирующая, как ее использовать:

@page "/"

<PageTitle>Home</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<BlazrInputSelect class = "form-select"
                  DisplayOptionsItems = "_countries"
                  OptionTextDelegate = "(x) => x.Name"
                  OptionValueDelegate = "(x) => x.Id.ToString()"
                  TValue = "Guid?"
                  TListItem = "Country"
                  @bind-Value = "_selectedCountryId" />

<div class = "bg-dark text-white m-2 p-2">
    <pre>@_selectedCountry</pre>
</div>
@code {
    private Guid? _selectedCountryId;

    private string _selectedCountry => _countries.SingleOrDefault(item => item.Id == _selectedCountryId)?.Name ?? "NoneSelected";

    public record Country(Guid Id, string Name, string Code);

    private List<Country> _countries = new()
    {
        new(Guid.NewGuid(), "United Kingdom", "GB"),
        new(Guid.NewGuid(), "France", "F"),
        new(Guid.NewGuid(), "Spain", "E"),
        new(Guid.NewGuid(), "Portugal", "P"),
    };
}

Вы должны быть в состоянии адаптировать это к своему контексту.

Ответ принят как подходящий

Вот код, который я использовал и начал работать:

    <h1>Expédition / Scanner</h1>

@if (Commandes == null)
{
    <p><em>Loading...</em></p>
    @* <div class = "spinner"></div> *@
}
else
{
    <EditForm Enhance Model = "CommandeNoForm" method = "post" FormName = "noCommandeInput" OnSubmit = "SubmitNoCommande">
        <div>
            <br/>
            <label>No de Commande</label>
            <br/>
            <InputSelect @bind-Value = "@CommandeNoForm.NoFacture">
                @foreach (var comm in Commandes))
                {
                    <option value = "@comm.NoFacture">@comm.NoFacture - @comm.ClientFacturation_NomClient</option>
                }
            </InputSelect>
        </div>
    </EditForm>



}


@code {

    [SupplyParameterFromForm]
    private CommandesDetailsModel CommandeNoForm { get; set; } = new();
    private void SubmitNoCommande()
    {

    }

    private IList<CommandesDetailsModel>? Commandes;
    private IList<CommandesDetailsModel>? CommandesDetails;

    protected override async Task OnInitializedAsync()
    {
        Commandes = (await AcombaSql.GetCommandesToShip()).ToList();
        CommandesDetails = (await AcombaSql.GetCommandesDetailsToShip()).ToList();
    }

}

Благодарим вас за вклад в сообщество Stack Overflow. Возможно, это правильный ответ, но было бы очень полезно предоставить дополнительные пояснения к вашему коду, чтобы разработчики могли понять ваши рассуждения. Это особенно полезно для новых разработчиков, которые не так хорошо знакомы с синтаксисом или пытаются понять концепции. Не могли бы вы отредактировать свой ответ, включив в него дополнительную информацию на благо сообщества?

Jeremy Caney 28.07.2024 23:27

Другие вопросы по теме