问题
The Hello World project template for Blazor includes a Weather Foreacast example (in addition to the Counter increment example).
I played around with this to see whats going on behind the scenes. I cant seem to figure it out.
Basically, if i comment out the line of code that fetched the weather .json data, then i see "Loading..." indefinitely. Makes sense thus far. But when i run it in its original state, i see "Loading..." then quickly followed by the rendering of the data grid. My confusion is that the rendering of the "Loading..." vs the datagrid is in an if-else statement. So this makes me believe that somehow this if-else is evaluated twice (once on load-time, and 2nd time once the data is loaded).
Questions
I'd like to know what is going on behind the scenes here:
- Is the if-else statement evaluated more than once?
- How else can it evaluate null and then render the grid when its asynchronously not null?
RESOLVED
I found my answer here. My suspicion was correct - the page is indeed rendered twice. The key to this is in the lifecycle of a component.
OnInit is called first, then OnInitAsync. Any asynchronous operations, which require the component to re-render once they complete, should be placed in the OnInitAsync method.
(Note that in the FetchData.cshtml the data is being loaded from OnInitAsync() override.)
回答1:
When you await a method ( OnInitAsync ), you yield control to the calling code, which continue to execute the rest of the code, rendering your component with the text "Loading...". When the Asynchronous method returns, that is, the task is completed, and new parameters are to be set, your control must be re-rendered to reflect the new changes. And of course the if-else statement runs once again, yielding a different result.
This actually has nothing to do with Blazor. This is how Asynchronous programming works in C#. However, the code in the ComponentBase class checks this conditions and decides when to re-render the component by calling the StateHasChanged method.
See ComponentBase.SetParameters and ComponentBase.ContinueAfterLifecycleTask to understand it better: https://github.com/aspnet/AspNetCore/blob/343208331d9ebbb3a67880133f4139bee2cb1c71/src/Components/src/Microsoft.AspNetCore.Components/ComponentBase.cs
Hope this helps...
回答2:
The if check is on null:
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
//table here
}
And the loading of the data is asynchronous. So when the page inits, the forecasts are null. Now the loading starts (async) and when that is finished it will populate the forecasts array. That will make it non-null and display the table.
Async is the key here I guess..
来源:https://stackoverflow.com/questions/53862159/how-does-the-blazor-weatherforecast-sample-work