Reputation: 165
I have Blazor components in a way similar to this:
Main.razor
@foreach (Vehicle vehicle in _vehicles)
{
if (vehicle.Visible)
{
<VehicleComponent Vehicle=@vehicle></VehicleComponent>
}
}
@code {
protected override void OnInitialized()
{
_vehicles = new List<Vehicles>();
// -> _vehicles being filled here
base.OnInitialized();
}
}
VehicleComponent.razor
@if (Vehicle != null)
{
<img src="@(Vehicle.src)"/>
<div id="@(Vehicle.Id)" tabindex="@(Vehicle.tabindex)">
<h3>@(Vehicle.text)</h3>
</div>
}
@code {
[Parameter] public Vehicle Vehicle { get; set; }
}
The problem is that all the VehicleComponent
s inside the loop are rendered after the loop is finished. But I want the component to completely render, before the next List item will be rendered.
I tried using StateHasChanged()
after each item in Main.razor
, but I got an infinite loop.
Is there a way I can render each component in the loop after each other (and update the UI)?
Upvotes: 1
Views: 7854
Reputation: 273179
If you want the visual effect of 'gradually appearing' items:
protected override async Task OnInitializedAsync ()
{
var temp = new List<Vehicles>();
// -> _vehicles being filled here
_vehicles = new List<Vehicles>();
foreach (var vehicle in temp)
{
_vehicles.Add(vehicle);
StateHasChanged();
await task.Delay(500); // adjust the delay to taste
}
}
but be aware that this is an expensive (slow) way to show them.
Using @key
won't improve this but it might help when you change the list later:
<VehicleComponent @key=vehicle Vehicle=@vehicle></VehicleComponent>
Upvotes: 7
Reputation: 30001
I think you are misunderstanding the Render process.
Your Razor code gets compiled into a C# class with your Razor compiled as a RenderFragment
(a delegate) - you can see it in the project obj/Debug/Net5
folder structure. The component "Render" events queue this delegate onto the Renderer's Queue. The Renderer executes these delegates and applies changes to the Renderer's DOM. Any changes in the Renderer's DOM get passed to the browser to modify it's DOM.
Henk's answer adds the items slowly to the list. It adds a "Render" event through StateHasChanged
and then yields through the Task.Delay
to let the Renderer re-render the list on each iteration.
Upvotes: 3