Accedere ai dati da un componente Blazor
I siti Web coinvolgenti devono visualizzare contenuti dinamici che possono cambiare in continuazione. Ottenere dati da un'origine dinamica, come ad esempio un database o un servizio Web, è una tecnica fondamentale nello sviluppo Web.
Si supponga di lavorare al sito Web rivolto ai clienti di un'azienda che consegna pizze. Il sito include una serie di pagine Web disposte e progettate come componenti Blazor. È necessario popolare le pagine con informazioni su pizze, condimenti e ordini e tali informazioni vanno ottenute da un database.
In questa unità viene illustrato come accedere ai dati ed eseguirne il rendering nel markup HTML per la visualizzazione da parte dell'utente.
Creazione di un servizio dati registrato
Se si vuole creare un sito Web dinamico che consenta agli utenti di visualizzare informazioni in aggiornamento, è necessario scrivere codice per ottenere tali dati da un'origine. Si supponga, ad esempio, di avere un database in cui sono archiviate tutte le pizze vendute dall'azienda. Poiché le pizze cambiano sempre, non è una buona idea impostarle come hardcoded nel codice HTML del sito Web. Usare invece il codice C# e Blazor per eseguire query sul database e quindi formattare i dettagli come HTML in modo che l'utente possa selezionare ciò che vuole.
In un'app Blazor Server è possibile creare un servizio registrato per rappresentare un'origine dati e ottenere dati da tale origine.
Nota
Le origini dati che è possibile usare in un'app Blazor includono database relazionali, database NoSQL, servizi Web, vari servizi di Azure e molti altri sistemi. Per eseguire query su tali origini è possibile usare tecnologie .NET come Entity Framework, client HTTP e ODBC. Queste tecniche non rientrano nell'ambito di questo modulo. In questo modulo viene illustrato come formattare e usare i dati ottenuti da una di queste origini e tecnologie.
La creazione di un servizio registrato inizia con la scrittura di una classe che ne definisce le proprietà. Ecco un esempio che è possibile scrivere per rappresentare una pizza:
namespace BlazingPizza.Data;
public class Pizza
{
public int PizzaId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public bool Vegetarian { get; set; }
public bool Vegan { get; set; }
}
La classe definisce le proprietà e i tipi di dati della pizza. È necessario assicurarsi che queste proprietà corrispondano allo schema della pizza nell'origine dati. È opportuno creare questa classe nella cartella Dati del progetto e usare uno spazio dei nomi membro denominato Dati. Se si preferisce, è possibile scegliere altre cartelle e spazi dei nomi.
È successivamente necessario definire il servizio:
namespace BlazingPizza.Data;
public class PizzaService
{
public Task<Pizza[]> GetPizzasAsync()
{
// Call your data access technology here
}
}
Si noti che il servizio usa una chiamata asincrona per accedere ai dati e restituire una raccolta di oggetti Pizza
. L'origine dati potrebbe essere remota rispetto al server in cui è in esecuzione il codice Blazor. In tal caso, usare una chiamata asincrona. Se l'origine dati risponde lentamente, è possibile continuare a eseguire altro codice in attesa della risposta.
È necessario registrare il servizio aggiungendo una riga alla sezione Add Services to the container
del file Program.cs:
...
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
// Register the pizzas service
builder.Services.AddSingleton<PizzaService>();
...
Uso di un servizio per ottenere dati
A questo punto usare il servizio definito chiamandolo in un componente Blazor e ottenendo i dati. Si supponga di avere il codice componente seguente e di voler visualizzare le pizze:
@page "/pizzas"
<h1>Choose your pizza</h1>
<p>We have all these delicious recipes:</p>
Inserimento del servizio
Prima di poter chiamare il servizio dal componente, è necessario usare l'inserimento delle dipendenze per aggiungere il servizio. Inserire il servizio aggiungendo il codice seguente dopo la direttiva @page
:
@using BlazingPizza.Data
@inject PizzaService PizzaSvc
In genere, il componente e il servizio si trovano in membri dello spazio dei nomi diversi, pertanto è necessario includere la direttiva @using
. Questa direttiva funziona allo stesso modo di un'istruzione using
all'inizio di un file di codice C#. La direttiva @inject
aggiunge il servizio al componente corrente e ne avvia un'istanza. Nella direttiva specificare il nome della classe del servizio. Farlo seguire dal nome che si vuole usare per l'istanza del servizio in questo componente.
Eseguire l'override del metodo OnInitializedAsync
Una buona posizione per chiamare il servizio e ottenere i dati è nel metodo OnInitializedAsync
. Questo evento viene generato quando l'inizializzazione del componente è stata completata e sono stati ricevuti i parametri iniziali, ma prima del rendering e della visualizzazione della pagina all'utente. L'evento viene definito nella classe di base del componente Blazor. È possibile eseguirne l'override in un blocco di codice come in questo esempio:
protected override async Task OnInitializedAsync()
{
\\ Call the service here
}
Chiamare un servizio per ottenere dati
Quando si chiama il servizio, usare la parola chiave await
perché la chiamata è asincrona:
private Pizza[] todaysPizzas;
protected override async Task OnInitializedAsync()
{
todaysPizzas = await PizzaSvc.GetPizzasAsync();
}
Visualizzazione dei dati all'utente
Dopo aver ottenuto alcuni dati dal servizio, si vuole che vengano visualizzati all'utente. Nell'esempio relativo alle pizze si prevede che il servizio restituisca un elenco di pizze tra cui gli utenti possono scegliere. Blazor include un set completo di direttive che è possibile usare per inserire questi dati nella pagina visualizzata dall'utente.
Verifica della presenza di dati
Determinare prima di tutto cosa viene visualizzato nella pagina prima del caricamento delle pizze. È possibile eseguire questa operazione controllando se la raccolta todaysPizzas
è null
. Per eseguire il codice di rendering condizionale in un componente Blazor, usare la direttiva @if
:
@if (todaysPizzas == null)
{
<p>We're finding out what pizzas are available today...</p>
}
else
{
<!-- This markup will be rendered once the pizzas are loaded -->
}
La direttiva @if
esegue il rendering del markup nel primo blocco di codice solo se l'espressione C# restituisce true
. È anche possibile usare un blocco di codice else if
per eseguire altri test ed eseguire il rendering del markup, se il risultato è true. Infine, è possibile specificare un blocco di codice else
per eseguire il rendering del codice se nessuna delle condizioni precedenti ha restituito true. Quando si verifica la presenza di valori null
nel blocco di codice @if
, ci si assicura che Blazor non tenti di visualizzare i dettagli della pizza prima che i dati vengano ottenuti dal servizio.
Nota
Blazor include anche la direttiva @switch
per eseguire il rendering del markup in base a un test che può restituire più valori. La direttiva @switch
funziona in modo analogo all'istruzione C# switch
.
Rendering di una raccolta di oggetti
Se Blazor esegue l'istruzione else
nel codice precedente, significa che alcune pizze sono state ottenute dal servizio. L'attività successiva consiste nel consentire all'utente di visualizzare queste pizze. È ora possibile esaminare come visualizzare i dati in una semplice tabella HTML.
Nel momento in cui si compila questa tabella non è possibile sapere quante pizze saranno disponibili. È possibile usare la direttiva @foreach
per riprodurre a ciclo continuo tutti gli oggetti nella raccolta todaysPizzas
ed eseguire il rendering di una riga per ognuno di essi:
<table>
<thead>
<tr>
<th>Pizza Name</th>
<th>Description</th>
<th>Vegetarian?</th>
<th>Vegan?</th>
<th>Price</th>
</tr>
</thead>
<tbody>
@foreach (var pizza in todaysPizzas)
{
<tr>
<td>@pizza.Name</td>
<td>@pizza.Description</td>
<td>@pizza.Vegetarian</td>
<td>@pizza.Vegan</td>
<td>@pizza.Price</td>
</tr>
}
</tbody>
</table>
Naturalmente, la gamma di pizze che si vuole visualizzare è più ricca rispetto alla tabella illustrata in questo esempio. Si vorranno anche formattare i prezzi e altri valori. Collaborare con i grafici per sviluppare un'interfaccia utente più accattivante. Ad esempio, includendo immagini di ogni pizza.
Nota
Blazor include altre direttive di ciclo, ad esempio @for
, @while
e @do while
. Queste direttive restituiscono blocchi di markup ripetuti. Funzionano in modo simile ai cicli C# for
, while
e do...while
equivalenti.
Nell'unità successiva si registrerà un servizio dati personalizzato.