I have a javascript event called Hello:
addEventListener('hello', function () {
alert("event listener");
})
and, in another javascript function, I raise the event:
let event = new Event("hello", { bubbles: true });
document.dispatchEvent(event);
What I want to do now is let the event trigger in a javascript function. Blazor should listen to the event, not javascript calling a Blazor method.
Hope anyone can assist me.
Regards me,
For anyone wondering the solution proposed by @Mister Magoo is no longer a preview for .NET 6 and is documented here with some exemples.
In a nutshell :
Create a C# class with the EventHandlerAttribute :
[EventHandler("oncityclicked", typeof(CustomSelectionCityEventArgs),
enableStopPropagation: true, enablePreventDefault: true)]
public static class EventHandlers
{
}
public class CustomSelectionCityEventArgs: EventArgs
{
public Guid Id { get; set; }
}
Add JS inside ./wwwroot/index.html and after <script src="_framework/blazor.webview.js" autostart="false"></script> :
<script>
Blazor.registerCustomEventType('cityclicked', {
createEventArgs: event => {
return {
id: event.detail
};
}
});
</script>
In you razor :
@code {
private void HandleCityClicked(CustomSelectionCityEventArgs eventArgs)
{
Console.WriteLine("Bouep");
}
}
<div id="CarteLeaflet" @oncityclicked="HandleCityClicked"></div>
And finally in the JS you can dispatch the event :
function OnMarkerClick(pId) {
const event = new CustomEvent('cityclicked', {
bubbles: true,
detail: pId
});
document.getElementById('CarteLeaflet').dispatchEvent(event);
}
Don't make the same mistake as me, the event name in the C# should start with "on" (JS : "cityclicked", C# : "oncityclicked").
For custom events, you will need to manually utilize JavaScript/.NET interoperability.
Using the Instance Method Call method:
- Pass the .NET instance by reference to JavaScript:
- Make a static call to DotNetObjectReference.Create.
- Wrap the instance in a DotNetObjectReference instance and call Create on the DotNetObjectReference instance. Dispose of DotNetObjectReference objects (an example appears later in this section).
- Invoke .NET instance methods on the instance using the
invokeMethodorinvokeMethodAsyncfunctions. The .NET instance can also be passed as an argument when invoking other .NET methods from JavaScript.
Note, this is a very simplified example. You probably want to add a few things; start by IDisposable on your interop classes to avoid memory leaks.
public class CustomEventHelper
{
private readonly Func<EventArgs, Task> _callback;
public CustomEventHelper(Func<EventArgs, Task> callback)
{
_callback = callback;
}
[JSInvokable]
public Task OnCustomEvent(EventArgs args) => _callback(args);
}
public class CustomEventInterop : IDisposable
{
private readonly IJSRuntime _jsRuntime;
private DotNetObjectReference<CustomEventHelper> Reference;
public CustomEventInterop(IJSRuntime jsRuntime)
{
_jsRuntime = jsRuntime;
}
public ValueTask<string> SetupCustomEventCallback(Func<EventArgs, Task> callback)
{
Reference = DotNetObjectReference.Create(new ScrollEventHelper(callback));
// addCustomEventListener will be a js function we create later
return _jsRuntime.InvokeAsync<string>("addCustomEventListener", Reference);
}
public void Dispose()
{
Reference?.Dispose();
}
}
Interop) and add a local method as a callback (HandleCustomEvent):private CustomEventInterop Interop { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender) {
if (!firstRender)
{
return;
}
Interop = new(JS);
await Interop.SetupCustomEventCallback(args => HandleCustomEvent(args));
HasRendered = true;
}
private void HandleCustomEvent(EventArgs args) {
// ... handle custom event here
}
DotNetObjectReference and can call the interop in C#:function addCustomEventListener(dotNetObjectRef) {
document.addEventListener('hello', (event) => {
// Calls a method by name with the [JSInokable] attribute (above)
dotNetObjectRef.invokeMethodAsync('OnCustomEvent')
});
}
If using TypeScript, you might check out this GitHub Issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With