ASP.NET vazby základních Blazor formulářů
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Upozorňující
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v tématu .NET a .NET Core Zásady podpory. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Tento článek vysvětluje, jak používat vazbu ve Blazor formulářích.
EditForm
/EditContext
model
EditContext Vytvoří EditForm na základě přiřazeného objektu kaskádovou hodnotu pro ostatní komponenty ve formuláři. Sleduje EditContext metadata procesu úprav, včetně toho, která pole formuláře byla změněna, a aktuální ověřovací zprávy. Přiřazení k formuláři EditForm.Model nebo k EditForm.EditContext datům může vytvořit vazbu.
Vazby modelu
Přiřazení:EditForm.Model
<EditForm ... Model="Model" ...>
...
</EditForm>
@code {
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
}
<EditForm ... Model="Model" ...>
...
</EditForm>
@code {
public Starship? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
}
Poznámka:
Většina příkladů modelu formulářů tohoto článku spojuje formuláře s vlastnostmi jazyka C#, ale vazba pole jazyka C# je podporována také.
Kontextová vazba
Přiřazení:EditForm.EditContext
<EditForm ... EditContext="editContext" ...>
...
</EditForm>
@code {
private EditContext? editContext;
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized()
{
Model ??= new();
editContext = new(Model);
}
}
<EditForm ... EditContext="editContext" ...>
...
</EditForm>
@code {
private EditContext? editContext;
public Starship? Model { get; set; }
protected override void OnInitialized()
{
Model ??= new();
editContext = new(Model);
}
}
Přiřaďte k Model EditContext objektu .EditForm Pokud jsou oba přiřazené, vyvolá se chyba za běhu.
Podporované typy
Vazba podporuje:
- Primitivní typy
- Kolekce
- Komplexní typy
- Rekurzivní typy
- Typy s konstruktory
- Výčty
Vazby [DataMember]
[IgnoreDataMember]
modelu můžete přizpůsobit také pomocí atributů. Pomocí těchto atributů můžete přejmenovat vlastnosti, ignorovat vlastnosti a označit vlastnosti jako povinné.
Další možnosti vazby
Při volání AddRazorComponentsjsou k dispozici RazorComponentsServiceOptions další možnosti vazby modelu:
- MaxFormMappingCollectionSize: Maximální počet prvků povolených v kolekci formulářů.
- MaxFormMappingRecursionDepth: Maximální povolená hloubka při rekurzivním mapování dat formuláře.
- MaxFormMappingErrorCount: Maximální počet chyb povolených při mapování dat formuláře.
- MaxFormMappingKeySize: Maximální velikost vyrovnávací paměti použité ke čtení datových klíčů formuláře.
Následující příklad ukazuje výchozí hodnoty přiřazené architekturou:
builder.Services.AddRazorComponents(options =>
{
options.FormMappingUseCurrentCulture = true;
options.MaxFormMappingCollectionSize = 1024;
options.MaxFormMappingErrorCount = 200;
options.MaxFormMappingKeySize = 1024 * 2;
options.MaxFormMappingRecursionDepth = 64;
}).AddInteractiveServerComponents();
Názvy formulářů
Pomocí parametru FormName přiřaďte název formuláře. Názvy formulářů musí být jedinečné pro vytvoření vazby dat modelu. Následující formulář má název RomulanAle
:
<EditForm ... FormName="RomulanAle" ...>
...
</EditForm>
Zadání názvu formuláře:
- Vyžaduje se pro všechny formuláře odeslané staticky vykreslenými komponentami na straně serveru.
- Nevyžaduje se u formulářů odesílaných interaktivně vykreslenými komponentami, které zahrnují formuláře v Blazor WebAssembly aplikacích a komponentách s interaktivním režimem vykreslování. Doporučujeme však zadat jedinečný název formuláře pro každý formulář, aby se zabránilo chybám při publikování za běhu formuláře, pokud dojde k vyřazení interaktivity formuláře.
Název formuláře je kontrolován pouze v případech, kdy se formulář publikuje do koncového bodu jako tradiční požadavek HTTP POST ze staticky vykreslené součásti na straně serveru. Architektura nevyvolá výjimku v okamžiku vykreslení formuláře, ale pouze v okamžiku, kdy přijde http POST a nezadá název formuláře.
Nad kořenovou komponentou aplikace je obor formuláře bez názvu (prázdný řetězec), který stačí, když v aplikaci nedojde ke kolizi názvu formuláře. Pokud jsou možné kolize názvů formulářů, například při zahrnutí formuláře z knihovny a nemáte žádnou kontrolu nad názvem formuláře používaným vývojářem knihovny, zadejte obor názvu formuláře s FormMappingScope komponentou v Blazor Web Apphlavním projektu.
V následujícím příkladu HelloFormFromLibrary
má komponenta název Hello
formuláře a je v knihovně.
HelloFormFromLibrary.razor
:
<EditForm FormName="Hello" Model="this" OnSubmit="Submit">
<InputText @bind-Value="Name" />
<button type="submit">Submit</button>
</EditForm>
@if (submitted)
{
<p>Hello @Name from the library's form!</p>
}
@code {
bool submitted = false;
[SupplyParameterFromForm]
private string? Name { get; set; }
private void Submit() => submitted = true;
}
Následující NamedFormsWithScope
komponenta používá komponentu knihovny HelloFormFromLibrary
a má také formulář s názvem Hello
. Název FormMappingScope oboru komponenty je ParentContext
určen pro všechny formuláře zadané komponentou HelloFormFromLibrary
. I když oba formuláře v tomto příkladu mají název formuláře (Hello
), názvy formulářů nejsou kolidovány a události jsou směrovány do správného formuláře pro události POST formuláře.
NamedFormsWithScope.razor
:
@page "/named-forms-with-scope"
<div>Hello form from a library</div>
<FormMappingScope Name="ParentContext">
<HelloFormFromLibrary />
</FormMappingScope>
<div>Hello form using the same form name</div>
<EditForm FormName="Hello" Model="this" OnSubmit="Submit">
<InputText @bind-Value="Name" />
<button type="submit">Submit</button>
</EditForm>
@if (submitted)
{
<p>Hello @Name from the app form!</p>
}
@code {
bool submitted = false;
[SupplyParameterFromForm]
private string? Name { get; set; }
private void Submit() => submitted = true;
}
Zadání parametru z formuláře ([SupplyParameterFromForm]
)
Atribut [SupplyParameterFromForm]
označuje, že hodnota přidružené vlastnosti by měla být zadána z dat formuláře pro formulář. Data v požadavku, která odpovídají názvu vlastnosti, jsou svázaná s vlastností. Vstupy založené na InputBase<TValue>
generování názvů hodnot formuláře, které odpovídají názvům Blazor , které se používají pro vazbu modelu. Na rozdíl od vlastností parametru komponenty ([Parameter]
), vlastnosti anotované pomocí [SupplyParameterFromForm]
nejsou nutné označit public
.
Pro atribut můžete zadat následující parametry vazby [SupplyParameterFromForm]
formuláře:
- Name: Získá nebo nastaví název parametru. Název se používá k určení předpony, která se má použít ke shodě dat formuláře, a rozhodnutí, zda má být hodnota vázána nebo ne.
- FormName: Získá nebo nastaví název obslužné rutiny. Název se používá ke shodě parametru s formulářem podle názvu formuláře, aby se rozhodl, zda je potřeba hodnotu vázat nebo ne.
Následující příklad nezávisle vytvoří vazbu dvou formulářů na jejich modely podle názvu formuláře.
Starship6.razor
:
@page "/starship-6"
@inject ILogger<Starship6> Logger
<EditForm Model="Model1" OnSubmit="Submit1" FormName="Holodeck1">
<div>
<label>
Holodeck 1 Identifier:
<InputText @bind-Value="Model1!.Id" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
<EditForm Model="Model2" OnSubmit="Submit2" FormName="Holodeck2">
<div>
<label>
Holodeck 2 Identifier:
<InputText @bind-Value="Model2!.Id" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
@code {
[SupplyParameterFromForm(FormName = "Holodeck1")]
private Holodeck? Model1 { get; set; }
[SupplyParameterFromForm(FormName = "Holodeck2")]
private Holodeck? Model2 { get; set; }
protected override void OnInitialized()
{
Model1 ??= new();
Model2 ??= new();
}
private void Submit1() => Logger.LogInformation("Submit1: Id={Id}", Model1?.Id);
private void Submit2() => Logger.LogInformation("Submit2: Id={Id}", Model2?.Id);
public class Holodeck
{
public string? Id { get; set; }
}
}
@page "/starship-6"
@inject ILogger<Starship6> Logger
<EditForm Model="Model1" OnSubmit="Submit1" FormName="Holodeck1">
<div>
<label>
Holodeck 1 Identifier:
<InputText @bind-Value="Model1!.Id" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
<EditForm Model="Model2" OnSubmit="Submit2" FormName="Holodeck2">
<div>
<label>
Holodeck 2 Identifier:
<InputText @bind-Value="Model2!.Id" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
@code {
[SupplyParameterFromForm(FormName = "Holodeck1")]
private Holodeck? Model1 { get; set; }
[SupplyParameterFromForm(FormName = "Holodeck2")]
private Holodeck? Model2 { get; set; }
protected override void OnInitialized()
{
Model1 ??= new();
Model2 ??= new();
}
private void Submit1() => Logger.LogInformation("Submit1: Id={Id}", Model1?.Id);
private void Submit2() => Logger.LogInformation("Submit2: Id={Id}", Model2?.Id);
public class Holodeck
{
public string? Id { get; set; }
}
}
Vnoření a vytvoření vazby formulářů
Následující doprovodné materiály ukazují, jak vnořit a svázat podřízené formuláře.
Následující třída podrobností o expediciShipDetails
obsahuje popis a délku podformulář.
ShipDetails.cs
:
namespace BlazorSample;
public class ShipDetails
{
public string? Description { get; set; }
public int? Length { get; set; }
}
namespace BlazorSample;
public class ShipDetails
{
public string? Description { get; set; }
public int? Length { get; set; }
}
Následující Ship
třída pojmenuje identifikátor (Id
) a obsahuje podrobnosti o expedici.
Ship.cs
:
namespace BlazorSample
{
public class Ship
{
public string? Id { get; set; }
public ShipDetails Details { get; set; } = new();
}
}
namespace BlazorSample
{
public class Ship
{
public string? Id { get; set; }
public ShipDetails Details { get; set; } = new();
}
}
Následující podformulář slouží k úpravě hodnot ShipDetails
typu. To je implementováno děděním Editor<T> v horní části komponenty. Editor<T> zajišťuje, aby podřízená komponenta vygenerovala správné názvy polí formuláře na základě modelu (T
), kde T
v následujícím příkladu je ShipDetails
.
StarshipSubform.razor
:
@inherits Editor<ShipDetails>
<div>
<label>
Description:
<InputText @bind-Value="Value!.Description" />
</label>
</div>
<div>
<label>
Length:
<InputNumber @bind-Value="Value!.Length" />
</label>
</div>
@inherits Editor<ShipDetails>
<div>
<label>
Description:
<InputText @bind-Value="Value!.Description" />
</label>
</div>
<div>
<label>
Length:
<InputNumber @bind-Value="Value!.Length" />
</label>
</div>
Hlavní formulář je vázán na Ship
třídu. Komponenta StarshipSubform
slouží k úpravě podrobností o expedici svázané jako Model!.Details
.
Starship7.razor
:
@page "/starship-7"
@inject ILogger<Starship7> Logger
<EditForm Model="Model" OnSubmit="Submit" FormName="Starship7">
<div>
<label>
Identifier:
<InputText @bind-Value="Model!.Id" />
</label>
</div>
<StarshipSubform @bind-Value="Model!.Details" />
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
@code {
[SupplyParameterFromForm]
private Ship? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
private void Submit() =>
Logger.LogInformation("Id = {Id} Desc = {Description} Length = {Length}",
Model?.Id, Model?.Details?.Description, Model?.Details?.Length);
}
@page "/starship-7"
@inject ILogger<Starship7> Logger
<EditForm Model="Model" OnSubmit="Submit" FormName="Starship7">
<div>
<label>
Identifier:
<InputText @bind-Value="Model!.Id" />
</label>
</div>
<StarshipSubform @bind-Value="Model!.Details" />
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
@code {
[SupplyParameterFromForm]
private Ship? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
private void Submit() =>
Logger.LogInformation("Id = {Id} Desc = {Description} Length = {Length}",
Model?.Id, Model?.Details?.Description, Model?.Details?.Length);
}
Inicializace dat formuláře pomocí statického SSR
Když komponenta přijme statickou službu SSR, spustí se metoda životního cyklu a OnParametersSet{Async}
metoda životního cyklu při OnInitialized{Async}
počátečním vykreslení komponenty a na každém formuláři POST na server. Chcete-li inicializovat hodnoty modelu formuláře, ověřte, zda model již obsahuje data před přiřazením nových hodnot modelu v OnParametersSet{Async}
, jak ukazuje následující příklad.
StarshipInit.razor
:
@page "/starship-init"
@inject ILogger<StarshipInit> Logger
<EditForm Model="Model" OnValidSubmit="Submit" FormName="StarshipInit">
<div>
<label>
Identifier:
<InputText @bind-Value="Model!.Id" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
@code {
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
protected override void OnParametersSet()
{
if (Model!.Id == default)
{
LoadData();
}
}
private void LoadData()
{
Model!.Id = "Set by LoadData";
}
private void Submit()
{
Logger.LogInformation("Id = {Id}", Model?.Id);
}
public class Starship
{
public string? Id { get; set; }
}
}
Pokročilé scénáře chyb mapování formulářů
Architektura vytvoří instanci formuláře a naplní FormMappingContext ho, což je kontext přidružený k operaci mapování daného formuláře. Vytvoří instanci každého oboru mapování (definovaného komponentouFormMappingScope).FormMappingContext Pokaždé, když se [SupplyParameterFromForm]
zeptá kontextu na hodnotu, architektura naplní FormMappingContext pokusnou hodnotou a všechny chyby mapování.
Vývojáři se neočekává, že budou pracovat FormMappingContext přímo, protože se jedná hlavně o zdroj dat pro InputBase<TValue>, EditContexta další interní implementace, které ukazují chyby mapování jako chyby ověřování. V pokročilých vlastních scénářích můžou vývojáři přistupovat FormMappingContext přímo jako k zápisu vlastního [CascadingParameter]
kódu, který využívá pokusy o hodnoty a chyby mapování.
Vlastní vstupní komponenty
V případě scénářů vlastního zpracování vstupu ukazují následující dílčí části vlastní vstupní komponenty:
Vstupní komponenta založená na
InputBase<T>
: Komponenta dědí z InputBase<TValue>, která poskytuje základní implementaci pro vazby, zpětné volání a ověřování. Součásti, které dědí od InputBase<TValue> , musí být použity ve formuláři Blazor (EditForm).Vstupní komponenta s úplným ovládáním pro vývojáře: Komponenta přebírá úplnou kontrolu nad zpracováním vstupu. Kód komponenty musí spravovat vazbu, zpětná volání a ověřování. Komponentu lze použít uvnitř formuláře nebo mimo ho Blazor .
Doporučujeme odvodit vlastní vstupní komponenty, pokud InputBase<TValue> vám to nezabrání konkrétní požadavky. Třída InputBase<TValue> je aktivně udržována týmem ASP.NET Core a zajišťuje, aby byla aktuální díky nejnovějším Blazor funkcím a změnám architektury.
Vstupní komponenta založená na InputBase<T>
Následující ukázková komponenta:
- Dědí z InputBase<TValue>. Součásti, které dědí od InputBase<TValue> , musí být použity ve formuláři Blazor (EditForm).
- Přebírá logický vstup ze zaškrtávacího políčka.
- Nastaví barvu pozadí kontejneru
<div>
na základě stavu zaškrtávacího políčka, ke kterému dojde přiAfterChange
spuštění metody po vazbě (@bind:after
). - Je nutné přepsat metodu
TryParseValueFromString
základní třídy, ale nezpracuje řetězcová vstupní data, protože zaškrtávací políčko neposkytuje řetězcová data. UkázkovéTryParseValueFromString
implementace pro jiné typy vstupních komponent, které zpracovávají řetězcový vstup, jsou k dispozici v referenčním zdroji ASP.NET Core.
Poznámka:
Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).
EngineeringApprovalInputDerived.razor
:
@using System.Diagnostics.CodeAnalysis
@inherits InputBase<bool>
<div class="@divCssClass">
<label>
Engineering Approval:
<input @bind="CurrentValue" @bind:after="AfterChange" class="@CssClass"
type="checkbox" />
</label>
</div>
@code {
private string? divCssClass;
private void AfterChange()
{
divCssClass = CurrentValue ? "bg-success text-white" : null;
}
protected override bool TryParseValueFromString(
string? value, out bool result,
[NotNullWhen(false)] out string? validationErrorMessage)
=> throw new NotSupportedException(
"This component does not parse string inputs. " +
$"Bind to the '{nameof(CurrentValue)}' property, " +
$"not '{nameof(CurrentValueAsString)}'.");
}
Pokud chcete použít předchozí komponentu ve formuláři příkladu hvězdicové lodi (Starship.cs
/Starship3.razor
), nahraďte <div>
blok pro pole EngineeringApprovalInputDerived
technického schválení instancí instancí komponenty vázanou na vlastnost modelu:IsValidatedDesign
- <div>
- <label>
- Engineering Approval:
- <InputCheckbox @bind-Value="Model!.IsValidatedDesign" />
- </label>
- </div>
+ <EngineeringApprovalInputDerived @bind-Value="Model!.IsValidatedDesign" />
Vstupní komponenta s úplným ovládáním pro vývojáře
Následující ukázková komponenta:
- Nedědí z InputBase<TValue>. Komponenta přebírá úplnou kontrolu nad zpracováním vstupu, včetně vazby, zpětných volání a ověřování. Komponentu lze použít uvnitř formuláře nebo mimo ho Blazor (EditForm).
- Přebírá logický vstup ze zaškrtávacího políčka.
- Změní barvu pozadí, pokud je políčko zaškrtnuté.
Kód v komponentě zahrnuje:
Vlastnost
Value
se používá s obousměrnou vazbou k získání nebo nastavení hodnoty vstupu.ValueChanged
je zpětné volání, které aktualizuje vázanou hodnotu.Při použití ve formuláři Blazor :
- Jedná se EditContext o kaskádovou hodnotu.
fieldCssClass
v závislosti na výsledku EditContext ověření pole styluje.ValueExpression
je výraz (Expression<Func<T>>
) přiřazený architekturou, která identifikuje vázanou hodnotu.- FieldIdentifier jedinečně identifikuje jedno pole, které lze upravit, obvykle odpovídající vlastnosti modelu. Identifikátor pole se vytvoří pomocí výrazu, který identifikuje vázanou hodnotu (
ValueExpression
).
V obslužné rutině
OnChange
události:- Hodnota vstupu zaškrtávacího políčka je získána z InputFileChangeEventArgs.
- Nastaví se barva pozadí a barva textu prvku kontejneru
<div>
. - EventCallback.InvokeAsync vyvolá delegáta přidruženého k vazbě a odešle oznámení události příjemcům, že se hodnota změnila.
- Pokud se komponenta používá v objektu EditForm (
EditContext
vlastnost nenínull
), EditContext.NotifyFieldChanged volá se k aktivaci ověření.
EngineeringApprovalInputStandalone.razor
:
@using System.Globalization
@using System.Linq.Expressions
<div class="@divCssClass">
<label>
Engineering Approval:
<input class="@fieldCssClass" @onchange="OnChange" type="checkbox"
value="@Value" />
</label>
</div>
@code {
private string? divCssClass;
private FieldIdentifier fieldIdentifier;
private string? fieldCssClass => EditContext?.FieldCssClass(fieldIdentifier);
[CascadingParameter]
private EditContext? EditContext { get; set; }
[Parameter]
public bool? Value { get; set; }
[Parameter]
public EventCallback<bool> ValueChanged { get; set; }
[Parameter]
public Expression<Func<bool>>? ValueExpression { get; set; }
protected override void OnInitialized()
{
fieldIdentifier = FieldIdentifier.Create(ValueExpression!);
}
private async Task OnChange(ChangeEventArgs args)
{
BindConverter.TryConvertToBool(args.Value, CultureInfo.CurrentCulture,
out var value);
divCssClass = value ? "bg-success text-white" : null;
await ValueChanged.InvokeAsync(value);
EditContext?.NotifyFieldChanged(fieldIdentifier);
}
}
Pokud chcete použít předchozí komponentu ve formuláři příkladu hvězdicové lodi (Starship.cs
/Starship3.razor
), nahraďte <div>
blok pro pole EngineeringApprovalInputStandalone
technického schválení instancí instancí komponenty vázanou na vlastnost modelu:IsValidatedDesign
- <div>
- <label>
- Engineering Approval:
- <InputCheckbox @bind-Value="Model!.IsValidatedDesign" />
- </label>
- </div>
+ <EngineeringApprovalInputStandalone @bind-Value="Model!.IsValidatedDesign" />
Komponenta EngineeringApprovalInputStandalone
je také funkční mimo EditForm:
<EngineeringApprovalInputStandalone @bind-Value="ValidDesign" />
<div>
<b>ValidDesign:</b> @ValidDesign
</div>
@code {
private bool ValidDesign { get; set; }
}
Přepínače
Příklad v této části je založen na Starfleet Starship Database
formuláři (Starship3
komponentě) části Příklad formuláře tohoto článku.
Do aplikace přidejte následující enum
typy . Vytvořte nový soubor pro jejich uložení nebo je přidejte do Starship.cs
souboru.
public class ComponentEnums
{
public enum Manufacturer { SpaceX, NASA, ULA, VirginGalactic, Unknown }
public enum Color { ImperialRed, SpacecruiserGreen, StarshipBlue, VoyagerOrange }
public enum Engine { Ion, Plasma, Fusion, Warp }
}
ComponentEnums
Zpřístupnění třídy pro:
Starship
model inStarship.cs
(napříkladusing static ComponentEnums;
).Starfleet Starship Database
form () (Starship3.razor
například@using static ComponentEnums
).
Pomocí InputRadio<TValue> komponent InputRadioGroup<TValue> vytvořte skupinu přepínačů. V následujícím příkladu Starship
se vlastnosti přidají do modelu popsaného v části Příklad formuláře článku o vstupních komponentách :
[Required]
[Range(typeof(Manufacturer), nameof(Manufacturer.SpaceX),
nameof(Manufacturer.VirginGalactic), ErrorMessage = "Pick a manufacturer.")]
public Manufacturer Manufacturer { get; set; } = Manufacturer.Unknown;
[Required, EnumDataType(typeof(Color))]
public Color? Color { get; set; } = null;
[Required, EnumDataType(typeof(Engine))]
public Engine? Engine { get; set; } = null;
Aktualizujte Starfleet Starship Database
formulář (Starship3
součást) části Příklad formuláře článku Vstupní komponenty. Přidejte komponenty, které se mají vytvořit:
- Skupina přepínačů pro výrobce lodi.
- Vnořená skupina přepínačů pro barvu motoru a lodi.
Poznámka:
Vnořené skupiny přepínačů se často nepoužívají ve formulářích, protože můžou vést k neuspořádanému rozložení ovládacích prvků formuláře, které můžou uživatele zmást. Existují však případy, kdy mají smysl v návrhu uživatelského rozhraní, například v následujícím příkladu, který spáruje doporučení pro dva vstupy uživatelů, modul lodí a barvu lodi. Ověření formuláře vyžaduje jeden modul a jednu barvu. Rozložení formuláře používá vnořené InputRadioGroup<TValue>čáry ke spárování motoru a doporučení barev. Uživatel ale může zkombinovat libovolný modul s libovolnou barvou a odeslat formulář.
Poznámka:
Ujistěte se, že ComponentEnums
je třída dostupná pro komponentu v následujícím příkladu:
@using static ComponentEnums
<fieldset>
<legend>Manufacturer</legend>
<InputRadioGroup @bind-Value="Model!.Manufacturer">
@foreach (var manufacturer in Enum.GetValues<Manufacturer>())
{
<div>
<label>
<InputRadio Value="manufacturer" />
@manufacturer
</label>
</div>
}
</InputRadioGroup>
</fieldset>
<fieldset>
<legend>Engine and Color</legend>
<p>
Engine and color pairs are recommended, but any
combination of engine and color is allowed.
</p>
<InputRadioGroup Name="engine" @bind-Value="Model!.Engine">
<InputRadioGroup Name="color" @bind-Value="Model!.Color">
<div style="margin-bottom:5px">
<div>
<label>
<InputRadio Name="engine" Value="Engine.Ion" />
Ion
</label>
</div>
<div>
<label>
<InputRadio Name="color" Value="Color.ImperialRed" />
Imperial Red
</label>
</div>
</div>
<div style="margin-bottom:5px">
<div>
<label>
<InputRadio Name="engine" Value="Engine.Plasma" />
Plasma
</label>
</div>
<div>
<label>
<InputRadio Name="color" Value="Color.SpacecruiserGreen" />
Spacecruiser Green
</label>
</div>
</div>
<div style="margin-bottom:5px">
<div>
<label>
<InputRadio Name="engine" Value="Engine.Fusion" />
Fusion
</label>
</div>
<div>
<label>
<InputRadio Name="color" Value="Color.StarshipBlue" />
Starship Blue
</label>
</div>
</div>
<div style="margin-bottom:5px">
<div>
<label>
<InputRadio Name="engine" Value="Engine.Warp" />
Warp
</label>
</div>
<div>
<label>
<InputRadio Name="color" Value="Color.VoyagerOrange" />
Voyager Orange
</label>
</div>
</div>
</InputRadioGroup>
</InputRadioGroup>
</fieldset>
Poznámka:
Pokud Name
je vynechán, InputRadio<TValue> komponenty jsou seskupené podle jejich nejnovějšího nadřazeného objektu.
Pokud jste implementovali předchozí kód v Starship3
komponentě příklad formuláře oddílu Vstupní komponenty článku, aktualizujte protokolování pro metoduSubmit
:Razor
Logger.LogInformation("Id = {Id} Description = {Description} " +
"Classification = {Classification} MaximumAccommodation = " +
"{MaximumAccommodation} IsValidatedDesign = " +
"{IsValidatedDesign} ProductionDate = {ProductionDate} " +
"Manufacturer = {Manufacturer}, Engine = {Engine}, " +
"Color = {Color}",
Model?.Id, Model?.Description, Model?.Classification,
Model?.MaximumAccommodation, Model?.IsValidatedDesign,
Model?.ProductionDate, Model?.Manufacturer, Model?.Engine,
Model?.Color);
Při práci s přepínači ve formuláři se datová vazba zpracovává jinak než jiné prvky, protože přepínače se vyhodnocují jako skupina. Hodnota každého přepínače je pevná, ale hodnota skupiny přepínačů je hodnota vybraného přepínače. Následující příklad ukazuje, jak:
- Zpracování datové vazby pro skupinu přepínačů
- Podpora ověřování pomocí vlastní InputRadio<TValue> komponenty
InputRadio.razor
:
@using System.Globalization
@inherits InputBase<TValue>
@typeparam TValue
<input @attributes="AdditionalAttributes" type="radio" value="@SelectedValue"
checked="@(SelectedValue.Equals(Value))" @onchange="OnChange" />
@code {
[Parameter]
public TValue SelectedValue { get; set; }
private void OnChange(ChangeEventArgs args)
{
CurrentValueAsString = args.Value.ToString();
}
protected override bool TryParseValueFromString(string value,
out TValue result, out string errorMessage)
{
var success = BindConverter.TryConvertTo<TValue>(
value, CultureInfo.CurrentCulture, out var parsedValue);
if (success)
{
result = parsedValue;
errorMessage = null;
return true;
}
else
{
result = default;
errorMessage = "The field isn't valid.";
return false;
}
}
}
Další informace o parametrech obecného typu (@typeparam
) najdete v následujících článcích:
- Referenční informace k syntaxi Razor pro ASP.NET Core
- komponenty ASP.NET Core Razor
- Komponenty ASP.NET Core Blazor bez vizuálního vzhledu
Použijte následující ukázkový model.
StarshipModel.cs
:
using System.ComponentModel.DataAnnotations;
namespace BlazorServer80
{
public class Model
{
[Range(1, 5)]
public int Rating { get; set; }
}
}
Následující RadioButtonExample
komponenta používá předchozí InputRadio
komponentu k získání a ověření hodnocení od uživatele:
RadioButtonExample.razor
:
@page "/radio-button-example"
@using System.ComponentModel.DataAnnotations
@using Microsoft.Extensions.Logging
@inject ILogger<RadioButtonExample> Logger
<h1>Radio Button Example</h1>
<EditForm Model="Model" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
@for (int i = 1; i <= 5; i++)
{
<div>
<label>
<InputRadio name="rate" SelectedValue="i"
@bind-Value="Model.Rating" />
@i
</label>
</div>
}
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
<div>@Model.Rating</div>
@code {
public StarshipModel Model { get; set; }
protected override void OnInitialized() => Model ??= new();
private void HandleValidSubmit()
{
Logger.LogInformation("HandleValidSubmit called");
}
}