Reputation: 169
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,
Upvotes: 8
Views: 19654
Reputation: 1186
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").
Upvotes: 15
Reputation: 7236
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.
Upvotes: 11