Question: When using Blazor RenderMode.Server, is there a way to add a loader or spinner
Hey guys. Long time listener, first time caller. I hope this is the correct place to ask this...
I'm using Blazor components in my existing Razor Pages app and calling them with
@(await Html.RenderComponentAsync<ComponentName>(RenderMode.Server))
I'm wondering if there is some way to know when the request is returned or ends so I could run a spinner or loader of some sort?
Disclaimer: I know very little about what I'm about to say.
I took a quick look at this from the "outside" (in a Blazor app itself, not the source) and it seems to enable this we'd need to expose some new API/callback on the window.Blazor object in the browser, such that one could register to be called back when a given component is loaded. Today, a unique marker is embedded in the HTML as a comment element, which contains a JSON payload that describes the component that will then be rendered over the circuit from the server once the page has loaded. The code to find these markers appears to all be internal and inaccessible, so doing anything today from inside the app would be pretty hacky. A new browser API would enable something low-level like this:
let marker = window.Blazor.getComponentMarker('someComponentMarkerField');
window.Blazor.onComponentLoading(marker, () => {
// Go ahead and do whatever to indicate the component is loading
let spinner = document.getElementById('myLoadingSpinner');
spinner...
});
window.Blazor.onComponentLoaded(marker, () => {
// Go ahead and do whatever to indicate the component is loaded
let spinner = document.getElementById('myLoadingSpinner');
spinner...
});
I think ideally we'd enable this scenario in a really nice way along with #13726 (Tag Helper for component rendering) such that you could just do something like this:
<component type="typeof(Counter)" render-mode="Server" id="myCounter" />
<component-loading for="myCounter">
loading...
</component-loading>
Alternate approach that simply augments the component Tag Helper itself:
<component type="typeof(Counter)" render-mode="Server" load-indicator="counterSpinner" />
<div id="counterSpinner">
This will be automatically hidden (display:none;) when the associated component finishes loading.
</div>
I think you'd want a separate element so that you have the flexibility to put the loading indicator anywhere on the page you like. You'd likely want to be able to support the following use-cases:
- a separate loader per component
- a shared loader used by multiple components
- a single loader for the entire page no matter which component is loading
Which use-cases we support will obviously impact which approach we take.
This is very similar functionality to the UpdateProgress control in Web forms and I agree it would be useful.
You could change your app element to show a spinner:
<app><img src="img/spinner.gif" /></app>
@pranavkm one doesn't always have an <app> element though right? If you're just rendering components in a Razor View, you don't need it.
Not works for me
<app>
@(await Html.RenderComponentAsync<App>(RenderMode.Server))
<div class="my-loader">
</div>
</app>
the div with class my-loader not disappear after the app is rendering, so my loader never disappear
Yup, I think @DamianEdwards is right. We'll have another look at this.
We've moved this issue to the Backlog milestone. This means that it is not going to happen for the coming release. We will reassess the backlog following the current release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources.
As a workaround, you can modify the blazor.webassembly.js, see this article on how to do this:
https://medium.com/@stef.heyenrath/show-a-loading-progress-indicator-for-a-blazor-webassembly-application-ea28595ff8c1
As a workaround, you can modify the
blazor.webassembly.js, see this article on how to do this: https://medium.com/@stef.heyenrath/show-a-loading-progress-indicator-for-a-blazor-webassembly-application-ea28595ff8c1
I dont know if webassembly is similar to server side blazor.
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
I have realised this function via the link which @StefH attached. But what badly is that I have to modify blazor.webassembly.js file Manually after each time I build my WASM application, even writing a script to do this duplicated step is still a trouble. What if to offer a native event or hook in blazor.webassembly.js file? As you see, it's not hard at all. Many Thanks.
just adding to the "this would be a nice feature" wagon :)
Streaming rendering in Blazor Web should cover this.