FetchData
,è il componente più complesso tra quelli del progetto di esempio
,segue
il codice :
@page
"/fetchdata"
@inject
HttpClient
Http
<PageTitle>Weather
forecast</PageTitle>
<h1>Weather
forecast</h1>
<p>This
component demonstrates fetching data from the server.</p>
@if
(forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table
class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp.
(C)</th>
<th>Temp.
(F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach
(var
forecast in
forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code
{
private
WeatherForecast[]?
forecasts;
protected
override
async
Task
OnInitializedAsync()
{
forecasts
= await
Http.GetFromJsonAsync<WeatherForecast[]>("sample-data/weather.json");
}
public
class
WeatherForecast
{
public
DateOnly
Date { get;
set;
}
public
int
TemperatureC { get;
set;
}
public
string?
Summary { get;
set;
}
public
int
TemperatureF => 32 + (int)(TemperatureC
/ 0.5556);
}
}
le
prime due righe contengono due direttive ,la direttiva page che
definisce la route e la direttiva inject che consente di utilizzare
l'HttpClient nella pagina,HttpClient è aggiunto ai servizi nel file
program.cs con la seguente istruzione :
builder.Services.AddScoped(sp
=> new
HttpClient { BaseAddress = new
Uri(builder.HostEnvironment.BaseAddress) });
segue
un “PageTitle” nell 'area @code troviamo definita una variabile
forecasts che può essere null ed è un array di oggetti
WeatherForecast
, nell'override del metodo OnInitializedAsync
viene caricata la variabile forecast , per fare ciò viene chiamato
il metodo GetFromJsonAsync di HttpClient il quale punta al file
“sample-data/weather.json”
,da notare che la classe WeatherForecast contiene 4 proprietà ,le
prime 3 sono valorizzate dalle proprietà con lo stesso nome presenti
nel json ,la quarta è una proprietà calcolata ovvero la temperatura
in gradi Fahrenheit ( TemperatureF ) partendo dalla temperatura in
gradi Celsius ( TemperatureC ) .
Logging:
di
default i progetti WebAssembly hanno abilitato un provider di logging
che scrive nella Console ,se dobbiamo far persistere i risultati
dobbiamo utilizzare un altro provider per il logging , segue
l'esempio del file Counter.razor che scrive nella Console, potete
vederla selezionando la finestra di output di visual studio :
@page
"/counter"
@inject
ILogger<Counter>
logger
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p
role="status">Current
count: @currentCount</p>
<button
class="btn
btn-primary"
@onclick="IncrementCount">Click
me</button>
@code
{
private
int
currentCount = 0;
private
void
IncrementCount()
{
logger.LogInformation("incremento
di 1");
currentCount++;
}
}
la
direttiva inject inietta il logger , dentro il metodo IncrementCount
viene aggiungiamo la riga logger.LogInformation(“incremento di 1”);
Abbiamo
6 livelli diversi di Logging (per il logging sotto
Microsoft.Extensions.Logging
)
qui li troviamo descritti
https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel?view=dotnet-plat-ext-8.0
E'
possibile usare altri provider di logging ,ad esempio Serilog
, qui
come utilizzarlo in Blazor .
Il
binding
Il
binding dei dati nei componenti può essere di due tipi :
1)One
way binding
2)Two
way binding
1)Un
esempio di one way binding è il componente Counter.razor (vedi
sopra) ,il metodo IncrementCount aumenta tramite l'operatore ++ il
valore di 1 e possiamo vedere aggiornato il valore di
@currentCount
2) quello che
segue è un esempio di two way binding in cui abbiamo dei campi di
input che vengono valorizzati dall'utente ed un risultato finale che
viene “calcolato” dall'applicazione :
creiamo
un componente BindTwoWay.razor con il seguente codice contenuto :
@page
"/BindTwoWay"
<h3>Bind
two ways </h3>
Titolo
del libro: <input
type="text"
@bind="TitoloLibro"/>
<br
/>
Letto
tutto :
<input
type="checkbox"
@bind="LettoTutto"
/>
<br
/>
Autore
:
<input
type="text"
@bind="Autore"
/>
<br
/>
<button
@onclick="Salva">Salva</button>
<p>@Messaggio</p>
@code
{
public
string?
TitoloLibro { get;
set;
}
public
bool
LettoTutto { get;
set;
}
public
string?
Autore { get;
set;
}
public
string?
Messaggio { get;
set;
}
private
void
Salva()
{
Messaggio
= TitoloLibro + ",
letto tutto: "
+ (LettoTutto ? "sì"
: "no")
+ ",
Autore:"
+ Autore;
TitoloLibro
= null;
Autore
= null;
LettoTutto
= false;
}
}
la
prima riga contiene la direttiva @page ovvero per chiamare questo
componente dovremmo chiamare /BindTwoWay , alla direttiva @bind
vengono assegnate tre variabili ovvero TitoloLibro , LettoTutto ,
Autore ,queste tre variabili sono dichiarate nell'area @code , grazie
a questa dichiarazione verrà assegnato alle variabili il valore
dichiarato nei campi di input ,il metodo Salva viene chiamato quando
l'utente clicca sul bottone in cui è assegnato ad @onclick il valore
Salva , questo metodo compone un messaggio utilizzando i valori che
arrivano dall'inputbox ed inoltre “svuota” i campi di input
mettendoli a null ed a false il valore relativo al checkbox il quale
viene quindi deselezionato qualora lo fosse ,compiliamo il form
chiamando
compiliamo i campi :
clicchiamo su Salva ed otteniamo :
La
navigazione in un sito Blazor
Per
navigare programmaticamente un sito possiamo utilizzare il componente
NavigationManager ,qui
la documentazione, segue un breve esempio , modifichiamo la pagina
Index così :
@page
"/"
@inject
NavigationManager
navman
<PageTitle>Index</PageTitle>
<h1>Hello
from index page!</h1>
<button
name="btNav"
@onclick="GoTo">Naviga
a counter</button>
<br
/>
<br
/>
<button
name="btNav1"
@onclick="UriAttuale">UriAttuale</button>
<button
name="btNav2"
@onclick="GoToUri">Navigare
all'uri nel textbox</button>
<input
name="uribox"
type="text"
@bind="UriValue"
/>
@code
{
public
string?
UriValue { get;
set;
}
private
void
GoTo()
{
navman.NavigateTo("/counter");
}
private
void
UriAttuale()
{
UriValue=navman.Uri;
}
private
void
GoToUri()
{
try
{
navman.NavigateTo(UriValue);
}
catch(Exception
ex)
{
//qui si potrebbe loggare l'errore :-)
UriValue
= ex.Message.ToString();
}
}
}
notiamo
l'uso della direttiva inject utilizzando la quale possiamo utilizzare
un oggetto di nome navman e di tipo NavigationManager ,quest'oggetto
fornisce il metodo NavigateTo che ci permette di navigare verso una
pagina programmaticamente,NavigationManager contiene anche la
proprietà Uri che restituisce l'indirizzo attuale del browser ,
il
metodo UriAttuale viene invocato a seguito del click sul bottone
btNav1 , il metodo assegna alla variabile UriValue il valore della
proprietà Uri e poiché la variabile è legata tramite direttiva
bind all'input box “uribox” il box risulta aggiornato con il
valore impostato nell'assegnazione
UriValue=navman.Uri;
il
metodo GoToUri viene chiamato quando si effettua il click sul bottone
di nome btNav2 , il metodo naviga all'indirizzo contenuto in “uribox”
ovvero ad UriValue ,nel caso si chiami GoToUri quando UriValue è
nullo il metodo NavigateTo genera un'eccezione che viene catturata e
valorizza l'”uribox”.Ripercorriamo il "flusso del programma" :
clicchiamo
sul bottone “Naviga a counter” ed otteniamo :
torniamo
alla index e clicchiamo sul bottone “UriAttuale” :
clicca sull'immagine per ingrandirlaclicchiamo
su F5 per fare il refresh della pagina , inseriamo /fetchdata del
text box
clicchiamo
sul bottone “Navigare all'uri nel textbox” ed otteniamo :
clicchiamo su "Navigare all'uri del textbox" con il textbox vuoto:
l'intero testo
d'errore è “Value cannot be null. (Parameter 'uri')” ,l'errore
si riferisce al parametro passato al metodo NavigateTo di
NavigationManager che non può essere nullo.
Per suggerimenti ,critiche o segnalazione errori potete inviare un email a gianmarco.castagna@gmail.com