Korzystanie z możliwości formularzy Blazor
- {liczbaMinut} minut
Użytkownicy wprowadzają dane przy użyciu formularzy. W klasycznej aplikacji internetowej utworzysz formularz przy użyciu <form> elementu i umożliwisz użytkownikowi dostarczanie danych przy użyciu <input> elementów. Gdy użytkownik prześle formularz, dane wejściowe można zweryfikować. Jeśli walidacja zakończy się pomyślnie, można wykonać odpowiednie akcje, takie jak użycie podanych informacji w celu dodania nowego wpisu do bazy danych lub zaktualizowania rekordu.
Udogodnienia zapewniane przez elementy <form> i <input> są proste, ale stosunkowo prymitywne. Platforma Blazor rozszerza możliwości formularzy przy użyciu jego <EditForm> składnika. Ponadto platforma Blazor udostępnia szereg wyspecjalizowanych elementów wejściowych, których można użyć do formatowania i weryfikowania danych wprowadzonych przez użytkownika.
W tej lekcji dowiesz się, jak używać <EditForm> elementu i elementów wejściowych do tworzenia formularzy funkcjonalnych. Zobaczysz również, jak używać powiązania danych z formularzem.
Co to jest formularz EditForm?
Element EditForm to składnik platformy Blazor, który spełnia rolę formularza HTML na stronie platformy Blazor. Główne różnice między formularzem EditForm i formularzem HTML są następujące:
- Powiązanie danych: obiekt można skojarzyć z formularzem EditForm. Formularz EditForm działa jak widok obiektu na potrzeby wprowadzania danych i wyświetlania.
-
Walidacja: Zapewnia
EditFormrozbudowane i rozszerzalne możliwości walidacji. Atrybuty można dodawać do elementów w obiekcieEditForm, które określają reguły walidacji.EditFormstosuje te reguły automatycznie. Ta funkcja jest opisana w dalszej lekcji w tym module. -
Przesyłanie formularza: formularz HTML przesyła żądanie POST do programu obsługi, gdy formularz zostanie przesłany. Ta procedura obsługi formularzy ma wykonać proces przesyłania, a następnie wyświetlić wszystkie wyniki. Element
EditFormjest zgodny z modelem zdarzeń platformy Blazor. Należy określić procedurę obsługi zdarzeń języka C#, która przechwytujeOnSubmitzdarzenie. Procedura obsługi zdarzeń wykonuje logikę przesyłania. -
Elementy wejściowe: formularz HTML używa kontrolki
<input>do zbierania danych wejściowych użytkownika isubmitprzycisku do publikowania formularza do przetwarzania. ObiektEditFormmoże używać tych samych elementów, ale platforma Blazor udostępnia bibliotekę składników wejściowych, które mają inne funkcje, takie jak wbudowane sprawdzanie poprawności i powiązanie danych.
Tworzenie obiektu EditForm z powiązaniem danych
Element <EditForm> obsługuje powiązanie danych z parametrem Model . Należy określić obiekt jako argument dla tego parametru. Elementy wejściowe w obiekcie EditForm mogą wiązać się z właściwościami i polami udostępnianymi przez model przy użyciu parametru @bind-Value . Poniższy przykład jest oparty na WeatherForecast klasie utworzonej przez domyślny szablon aplikacji serwera Blazor. Klasa wygląda następująco:
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string Summary { get; set; }
}
Model dla EditForm klasy jest wystąpieniem WeatherForecast klasy przechowywanej w zmiennej @currentForecast , a elementy wejściowe są powiązane z polami w klasie:
@page "/fetchdata"
@using WebApplication.Data
@inject WeatherForecastService ForecastService
<h1>Weather forecast</h1>
<input type="number" width="2" min="0" max="@upperIndex" @onchange="ChangeForecast" value="@index"/>
<EditForm Model=@currentForecast>
<InputDate @bind-Value=currentForecast.Date></InputDate>
<InputNumber @bind-Value=currentForecast.TemperatureC></InputNumber>
<InputText @bind-Value=currentForecast.Summary></InputText>
</EditForm>
@code {
private WeatherForecast[] forecasts;
private WeatherForecast currentForecast;
private int index = 0;
private int upperIndex = 0;
protected override async Task OnInitializedAsync()
{
forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
currentForecast = forecasts[index];
upperIndex = forecasts.Count() - 1;
}
private async Task ChangeForecast(ChangeEventArgs e)
{
index = int.Parse(e.Value as string);
if (index <= upperIndex && index >= 0)
{
currentForecast = forecasts[index];
}
}
}
W tym przykładzie OnInitialized zdarzenie wypełnia tablicę WeatherForecast obiektów przy użyciu usługi zewnętrznej. Zmienna currentForecast jest ustawiona na pierwszy element w tablicy; jest to obiekt wyświetlany przez EditForm. Użytkownik może przechodzić przez tablicę przy użyciu pola wejściowego liczbowego powyżej EditForm strony. Wartość tego pola jest używana jako indeks tablicy, a currentForecast zmienna jest ustawiana na obiekt znaleziony w tym indeksie ChangeForecast przy użyciu metody .
Na poniższej ilustracji przedstawiono przykład uruchomionej strony:
Important
Składnik EditForm implementuje dwukierunkowe powiązanie danych. Formularz wyświetla wartości pobrane z trybu. Jeśli jednak użytkownik zaktualizuje te wartości w formularzu, wartości zostaną wypchnięte z powrotem do modelu.
Omówienie kontrolek wejściowych platformy Blazor
Element HTML <form> obsługuje <input> element, aby umożliwić użytkownikowi wprowadzanie danych. Obiekt <input> ma type właściwość, która określa typ danych wejściowych i sposób jego wyświetlania; jako liczba, pole tekstowe, przycisk radiowy, pole wyboru, przycisk itd.
Platforma Blazor ma własny zestaw składników przeznaczonych do pracy z elementem <EditForm> i obsługuje powiązanie danych między innymi funkcjami. W poniższej tabeli wymieniono te składniki. Gdy platforma Blazor renderuje stronę zawierającą te składniki, są one konwertowane na odpowiednie elementy <input> HTML wymienione w tabeli. Niektóre składniki platformy Blazor są ogólne; Środowisko uruchomieniowe platformy Blazor określa parametr typu w zależności od typu danych powiązanych z elementem:
| Składnik wejściowy | Renderowane jako (HTML) |
|---|---|
InputCheckbox |
<input type="checkbox"> |
InputDate<TValue> |
<input type="date"> |
InputFile |
<input type="file"> |
InputNumber<TValue> |
<input type="number"> |
InputRadio<TValue> |
<input type="radio"> |
InputRadioGroup<TValue> |
Grupa podrzędnych przycisków radiowych |
InputSelect<TValue> |
<select> |
InputText |
<input> |
InputTextArea |
<textarea> |
Każdy z tych elementów ma atrybuty rozpoznawane przez platformę Blazor. Przykłady, takie jak DisplayName, które są używane do skojarzenia elementu wejściowego z etykietą, i @ref, których można użyć do zapisania odwołania do pola w zmiennej języka C#. Wszystkie nierozpoznane atrybuty inne niż Blazor są przekazywane bez zmian do modułu renderowania HTML. Oznacza to, że można użyć atrybutów elementu wejściowego HTML. Można na przykład dodać minatrybuty , maxi step do InputNumber składnika i działają prawidłowo jako część renderowanego <input type="number"> elementu. W poprzednim przykładzie można określić TemperatureC pole wejściowe jako:
<EditForm Model=@currentForecast>
<InputNumber @bind-Value=currentForecast.TemperatureC width="5" min="-100" step="5"></InputNumber>
</EditForm>
W następnym przykładzie pokazano, jak używać InputRadioGroup<TValue> składników i InputRadio<TValue> . Zazwyczaj używa się grupy przycisków radiowych do prezentowania serii przycisków radiowych. Każdy przycisk umożliwia użytkownikowi wybranie jednej wartości z danego zestawu. Element EditForm może zawierać wiele RadioButtonGroup<TValue> składników, a każda grupa może być powiązana z polem w modelu dla elementu EditForm. W poniższym przykładzie przedstawiono szczegółowe informacje z aplikacji sklepu odzieżowego. Formularz wyświetla dane dotyczące T-shirtów. Klasa Shirt modelu wygląda następująco:
public enum ShirtColor
{
Red, Blue, Yellow, Green, Black, White
};
public enum ShirtSize
{
Small, Medium, Large, ExtraLarge
};
public class Shirt
{
public ShirtColor Color { get; set; }
public ShirtSize Size { get; set; }
public decimal Price;
}
Zwróć uwagę, że kolor i rozmiar koszulki są określane jako wyliczenia. Na poniższej stronie Razor kod tworzy Shirt obiekt do działania jako dane testowe. Element <EditForm> jest powiązany z tym obiektem. Formularz wyświetla rozmiar, kolor i cenę koszulki. Pierwszy <InputRadioGroup> element jest dołączony do Size właściwości . Pętla foreach iteruje możliwe wartości w wyliczenie i tworzy <InputRadio> element dla każdego z nich. Atrybut Name<InputRadio> elementu musi być zgodny z elementem <InputRadioGroup> ; program renderujący HTML używa tego atrybutu do łączenia grup i przycisków radiowych. Drugi <InputRadioGroup> element jest dołączony do Color właściwości i używa tej samej techniki do generowania przycisków radiowych dla każdego rozmiaru. Ostatni element wyświetla cenę przy użyciu <InputNumber> elementu. Ten element stosuje maxatrybuty , mini step dostępne dla elementu HTML <input> . W tym przykładzie użyto <label> elementów do wyświetlenia nazwy wartości skojarzonej z każdym składnikiem.
<EditForm Model="@shirt">
<label>
<h3>Size</h3>
<InputRadioGroup Name="size" @bind-Value=shirt.Size>
@foreach(var shirtSize in Enum.GetValues(typeof(ShirtSize)))
{
<label>@shirtSize:
<InputRadio Name="size" Value="@shirtSize"></InputRadio>
</label>
<br />
}
</InputRadioGroup>
</label>
<p></p>
<label>
<h3>Color</h3>
<InputRadioGroup Name="color" @bind-Value=shirt.Color>
@foreach(var shirtColor in Enum.GetValues(typeof(ShirtColor)))
{
<label>@shirtColor:
<InputRadio Name="color" Value="@shirtColor"></InputRadio>
</label>
<br />
}
</InputRadioGroup>
</label>
<p></p>
<label>
<h3>Price</h3>
<InputNumber @bind-Value=shirt.Price min="0" max="100" step="0.01"></InputNumber>
</label>
</EditForm>
@code {
private Shirt shirt = new Shirt
{
Size = ShirtSize.Large,
Color = ShirtColor.Blue,
Price = 9.99M
};
}
Po uruchomieniu formularza wygląda następująco:
Obsługa przesyłania formularza
Zobaczyliśmy, że można użyć elementu EditForm , aby zmodyfikować dane w modelu bazowym. Po zakończeniu wprowadzania zmian możesz przesłać formularz, aby zweryfikować dane na serwerze i zapisać zmiany. Platforma Blazor obsługuje dwa typy weryfikacji; deklaratywny i programowy. Reguły walidacji deklaratywnej działają na kliencie w przeglądarce. Są one przydatne do przeprowadzania podstawowej weryfikacji po stronie klienta przed przesłaniem danych na serwer. Walidacja po stronie serwera jest przydatna w przypadku obsługi złożonych scenariuszy, które nie są dostępne w przypadku walidacji deklaratywnej, takich jak krzyżowe sprawdzanie danych w polu względem danych z innych źródeł. Rzeczywista aplikacja powinna korzystać z kombinacji weryfikacji po stronie klienta i po stronie serwera. Walidacja po stronie klienta wychwytuje podstawowe błędy danych wejściowych użytkownika i zapobiega wielu przypadkom nieprawidłowych danych wysyłanych do serwera do przetwarzania. Weryfikacja po stronie serwera gwarantuje, że żądanie użytkownika do zapisania danych nie próbuje pominąć weryfikacji danych i przechowywać niekompletne lub uszkodzone dane.
Note
Można również wychwycić zdarzenia języka JavaScript, takie jak onchange i oninput, oraz równoważne @onchange i @oninput zdarzenia platformy Blazor dla wielu kontrolek w elemencie EditForm. Za pomocą tych zdarzeń można programowo sprawdzać i weryfikować dane w poszczególnych polach przed przesłaniem formularza przez użytkownika. Jednak takie podejście nie jest zalecane. Może to być frustrujące dla użytkownika, aby komunikaty sprawdzania poprawności były wyświetlane podczas wprowadzania każdego naciśnięcia lub karty między polami. Zapisz walidację po zakończeniu wprowadzania danych przez użytkownika.
Po przesłaniu elementu EditForm są uruchamiane następujące trzy zdarzenia:
-
OnValidSubmit: To zdarzenie jest wyzwalane, jeśli pola wejściowe pomyślnie przekazują reguły walidacji zdefiniowane przez ich atrybuty weryfikacji. -
OnInvalidSubmit: To zdarzenie jest wyzwalane, jeśli którekolwiek z pól wejściowych w formularzu zakończy się niepowodzeniem weryfikacji zdefiniowanej przez ich atrybuty weryfikacji. -
OnSubmit: To zdarzenie występuje, gdy formularz EditForm jest przesyłany niezależnie od tego, czy wszystkie pola wejściowe są prawidłowe, czy nie.
Zdarzenia OnValidSubmit i OnInvalidSubmit są przydatne w przypadku elementu EditForm, który implementuje podstawową walidację na poziomie poszczególnych pól wejściowych. Jeśli masz bardziej złożone wymagania dotyczące walidacji, takie jak krzyżowe sprawdzanie jednego pola wejściowego względem innego w celu zapewnienia prawidłowej kombinacji wartości, rozważ użycie OnSubmit zdarzenia.
EditForm może obsługiwać parę zdarzeń OnValidSubmit i OnInvalidSubmit lub zdarzenie OnSubmit, ale nie wszystkie trzy. Przesyłanie jest wyzwalane przez dodanie Submit przycisku do elementu EditForm. Gdy użytkownik wybierze ten przycisk, zostaną wyzwolone zdarzenia przesyłania określone przez element EditForm .
Note
Proces kompilacji i wdrażania nie sprawdza nieprawidłowej kombinacji zdarzeń przesyłania, ale niedozwolony wybór powoduje błąd w czasie wykonywania programu. Jeśli na przykład próbujesz użyć OnValidSubmit z OnSubmit, aplikacja generuje następujący wyjątek czasu wykonywania:
Error: System.InvalidOperationException: When supplying an OnSubmit parameter to EditForm, do not also supply OnValidSubmit or OnInvalidSubmit.
Stan bieżącego obiektu, który działa jako model, jest śledzony przy użyciu obiektu EditForm, w tym które pola zostały zmienione i jakie są ich bieżące wartości przez EditContext. Obiekt EditContext jest przekazywany do zdarzeń przesyłania jako parametr. Program obsługi zdarzeń może użyć Model pola w tym obiekcie, aby pobrać dane wejściowe użytkownika.
W poniższym przykładzie pokazano element EditForm z poprzedniego przykładu z przyciskiem prześlij. Przechwytuje EditForm zdarzenie w OnSubmit celu zweryfikowania zmian wprowadzonych w obiekcie T-shirt. W tym przykładzie dozwolone są tylko niektóre kombinacje wartości:
- Czerwone koszulki nie są dostępne w rozmiarze Extra Large.
- Niebieskie koszulki nie są dostępne w małych lub średnich rozmiarach.
- Białe koszulki mają maksymalną cenę 50 USD.
Jeśli wykryto niedozwoloną kombinację, Message pole w formularzu wyświetla przyczynę niepowodzenia walidacji. Jeśli pola są prawidłowe, dane są przetwarzane, a dane są zapisywane (logika tego procesu nie jest wyświetlana).
<EditForm Model="@shirt" OnSubmit="ValidateData">
<!-- Omitted for brevity -->
<input type="submit" class="btn btn-primary" value="Save"/>
<p></p>
<div>@Message</div>
</EditForm>
@code {
private string Message = String.Empty;
// Omitted for brevity
private async Task ValidateData(EditContext editContext)
{
if (editContext.Model isn't Shirt shirt)
{
Message = "T-Shirt object is invalid";
return;
}
if (shirt is { Color: ShirtColor.Red, Size: ShirtSize.ExtraLarge })
{
Message = "Red T-Shirts not available in Extra Large size";
return;
}
if (shirt is { Color: ShirtColor.Blue, Size: <= ShirtSize.Medium)
{
Message = "Blue T-Shirts not available in Small or Medium sizes";
return;
}
if (shirt is { Color: ShirtColor.White, Price: > 50 })
{
Message = "White T-Shirts must be priced at 50 or lower";
return;
}
// Data is valid
// Save the data
Message = "Changes saved";
}
}
Na poniższej ilustracji przedstawiono wyniki, jeśli użytkownik próbuje podać nieprawidłowe dane: