I am playing with the Blazor Webassembly template, specifically the weather forecast page.
I simply add a timer and have a function that increments a variable, that is shown on the page. What I don't get is, the addText function is never called specifically, and yet the variable keeps incrementing with the timer elapsed. So I don't understand what is happening here.
Could someone enlighten me? Do all functions within the html area get called on StateHasChanged() or something? If I changed the line in the html to '@((MarkupString)sometext.ToString())', it doesn't increment. Here is the code:
<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>
<br />
@((MarkupString)addText())
}
@code {
private WeatherForecast[] forecasts;
private int sometext = 0;
Timer timer;
protected override async Task OnInitializedAsync()
{
timer = new Timer();
timer.Interval = 1000;
timer.Elapsed += TimerOnElapsed;
timer.Start();
forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
}
private void TimerOnElapsed(object sender, ElapsedEventArgs e)
{
StateHasChanged();
}
private string addText()
{
return sometext++.ToString();
}
}
StateHaseChanged
is forcing a render. The render is calling the function... The Markup area is compiled to a delegate which is called on render. Your function is just a subroutine call. You are counting the render calls.
<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>
<br />
@sometext
}
@code {
private WeatherForecast[] forecasts;
private int sometext = 0;
Timer timer;
protected override async Task OnInitializedAsync()
{
timer = new Timer();
timer.Interval = 1000;
timer.Elapsed += TimerOnElapsed;
timer.Start();
forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
}
private void TimerOnElapsed(object sender, ElapsedEventArgs e)
{
sometext++;
StateHasChanged(); // <- probably not needed not sure
}
}