Make DOM element JavaScript lifecycle callbacks declarable in Razor syntax
See original GitHub issueInspired by @SQL-MisterMagoo’s issue #17472, I suggest the following generalized solution:
Describe the solution you’d like
When defining a HTML element to be rendered in the browser in Blazor, it should be possible to specify JavaScript functions that are executed in the context of that HTML element, when it is first rendered, rendered, and disposed/removed from the DOM.
For example, the Dropdown Bootstrap component could look like this then (this is just for illustration purposes, not a complete implementation):
<div class="dropdown">
<button @onFirstRender="boostrapInteropt.dropdownInit(@dotnetHelper)"
@onRender="boostrapInteropt.dropdownRender()"
@onDispose="boostrapInteropt.dropdownDispose()"
class="btn btn-secondary dropdown-toggle" ...>
Dropdown button
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</div>
@code {
private DotNetObjectReference dotnetHelper = DotNetObjectReference.Create(...);
}
where this
in each function call is bound to the rendered DOM element. This assumes an JavaScript object exists such as:
window.boostrapInteropt {
dropdownInit: function(dotnetHelper) {
$(this).dropdown();
// ...
},
dropdownRender: function() {
$(this).dropdown('update');
// ...
},
dropdownDispose: function() {
$(this).dropdown('dispose');
// ...
}
}
Note, it should be possible to pass arguments to the JavaScript functions as it is through the normal JsRuntime’s invoke methods. In the example above, we are passing a dotnetHelper callback object.
This will enable simple and consistent integration with existing JavaScript based components, that usually surface methods such as init
and destroy/dispose
. It ensures JavaScript objects are correctly cleaned up and functionality is available as soon as possible to the end user.
Why not use razor lifecycle methods and JsRuntime.InvokeAsync(...)
?
The problem with OnAfterRender
is that it is first called after the element is visible to the users. In Blazor Server scenarios, the round-trip network delay can be high enough, that the user will experience elements not working probably or visually moving on the screen, e.g. if using popper.js
to position elements.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:8
- Comments:5 (5 by maintainers)
That should give us plenty of time to work on a proof of concept 😁 I’ve got a very basic version working now, we can always provide an alternative js file for the brave ones to play with.
That is fair @javiercn.
One additional point I would like to make is that this will make it easier to integrate existing JavaScript components with Blazor, which will likely help increase adoption of Blazor. The important point is that it will make it possible to make the integration consistent between Blazor Server and Blazor Wasm.