[英]Blazor listen to javascript event
I have a javascript event called Hello:我有一个名为 Hello 的 javascript 事件:
addEventListener('hello', function () {
alert("event listener");
})
and, in another javascript function, I raise the event:并且,在另一个 javascript 函数中,我引发了事件:
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.我现在要做的是让事件在 javascript 函数中触发。 Blazor should listen to the event, not javascript calling a Blazor method.
Blazor 应该监听事件,而不是调用 Blazor 方法的 javascript。
Hope anyone can assist me.希望任何人都可以帮助我。
Regards me,问候我,
For custom events, you will need to manually utilize JavaScript/.NET interoperability .对于自定义事件,您需要手动利用JavaScript/.NET 互操作性。
Using the Instance Method Call method:使用实例方法调用方法:
- Pass the .NET instance by reference to JavaScript:
通过引用 JavaScript 传递 .NET 实例:
- Make a static call to DotNetObjectReference.Create.
对 DotNetObjectReference.Create 进行 static 调用。
- Wrap the instance in a DotNetObjectReference instance and call Create on the DotNetObjectReference instance.
将实例包装在 DotNetObjectReference 实例中并在 DotNetObjectReference 实例上调用 Create。 Dispose of DotNetObjectReference objects (an example appears later in this section).
处理 DotNetObjectReference 对象(本节后面会显示一个示例)。
- Invoke .NET instance methods on the instance using the
invokeMethod
orinvokeMethodAsync
functions.使用
invokeMethod
或invokeMethodAsync
函数在实例上调用 .NET 实例方法。 The .NET instance can also be passed as an argument when invoking other .NET methods from JavaScript.当从 JavaScript 调用其他 .NET 方法时,.NET 实例也可以作为参数传递。
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 .从您的互操作类上的
IDisposable
开始, 以避免 memory 泄漏。
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
):Interop
) 的实例并添加本地方法作为回调 ( 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#:DotNetObjectReference
的方法,可以调用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 .如果使用 TypeScript,您可以查看此GitHub 问题。
For anyone wondering the solution proposed by @Mister Magoo is no longer a preview for .NET 6 and is documented here with some exemples.对于任何想知道@Mister Magoo 提出的解决方案不再是 .NET 6 的预览并且在此处记录了一些示例的人。
In a nutshell:简而言之:
Create a C# class with the EventHandlerAttribute:使用 EventHandlerAttribute 创建一个 C# 类:
[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>
:在
./wwwroot/index.html
和<script src="_framework/blazor.webview.js" autostart="false"></script>
之后添加 JS:
<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:最后在 JS 中你可以发送事件:
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").不要和我犯同样的错误,C#中的事件名称应该以“on”开头(JS:“cityclicked”,C#:“oncityclicked”)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.