我有一个名为Hello:的javascript事件
addEventListener('hello', function () {
alert("event listener");
})
在另一个javascript函数中,我引发了事件:
let event = new Event("hello", { bubbles: true });
document.dispatchEvent(event);
我现在想做的是让事件在javascript函数中触发。Blazor应该监听事件,而不是javascript调用Blazor方法。
希望有人能帮助我。
问候我,
对于自定义事件,您需要手动利用JavaScript/.NET互操作性。
使用实例方法调用方法:
- 通过引用JavaScript传递.NET实例:
- 对DotNetObjectReference.Create进行静态调用
- 将该实例包装在DotNetObjectReference实例中,并对该DotNetObjectReference实例调用Create。处置DotNetObjectReference对象(本节稍后将显示一个示例(
- 使用
invokeMethod
或invokeMethodAsync
函数在实例上调用.NET实例方法。当从JavaScript调用其他.NET方法时,.NET实例也可以作为参数传递
示例
注意,这是一个非常简单的例子。您可能想要添加一些内容;从interop类上的IDisposable
开始,以避免内存泄漏。
- 在C#中,创建一个助手类来管理互操作:
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();
}
}
- 在Blazor组件中,添加互操作类的实例(
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
}
- 在JavaScript中,添加一个引用
DotNetObjectReference
并可以在C#中调用interop的方法:
function addCustomEventListener(dotNetObjectRef) {
document.addEventListener('hello', (event) => {
// Calls a method by name with the [JSInokable] attribute (above)
dotNetObjectRef.invokeMethodAsync('OnCustomEvent')
});
}
如果使用TypeScript,您可以查看此GitHub问题。
对于那些想知道@Mister Magoo提出的解决方案不再是.NET 6的预览版的人来说,这里有一些示例。
简而言之:
创建一个具有EventHandlerAttribute的C#类:
[EventHandler("oncityclicked", typeof(CustomSelectionCityEventArgs),
enableStopPropagation: true, enablePreventDefault: true)]
public static class EventHandlers
{
}
public class CustomSelectionCityEventArgs: EventArgs
{
public Guid Id { get; set; }
}
在./wwwroot/index.html
内部和<script src="_framework/blazor.webview.js" autostart="false"></script>
之后添加JS:
<script>
Blazor.registerCustomEventType('cityclicked', {
createEventArgs: event => {
return {
id: event.detail
};
}
});
</script>
在你的剃刀:
@code {
private void HandleCityClicked(CustomSelectionCityEventArgs eventArgs)
{
Console.WriteLine("Bouep");
}
}
<div id="CarteLeaflet" @oncityclicked="HandleCityClicked"></div>
最后,在JS中,您可以调度事件:
function OnMarkerClick(pId) {
const event = new CustomEvent('cityclicked', {
bubbles: true,
detail: pId
});
document.getElementById('CarteLeaflet').dispatchEvent(event);
}
不要犯和我一样的错误,C#中的事件名称应该以"开头;关于";(JS:"cityclicated",C#:"oncityclicked"(。