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 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
invokeMethod
orinvokeMethodAsync
functions. 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.