Я только что прошел курс по 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();
}
}
Поскольку собрать рабочий пример на основе вашего кода сложно, я создал демо-версию.
Сначала специальный компонент на основе 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. Возможно, это правильный ответ, но было бы очень полезно предоставить дополнительные пояснения к вашему коду, чтобы разработчики могли понять ваши рассуждения. Это особенно полезно для новых разработчиков, которые не так хорошо знакомы с синтаксисом или пытаются понять концепции. Не могли бы вы отредактировать свой ответ, включив в него дополнительную информацию на благо сообщества?