Tec*_*iel 8 .net javascript interop webassembly blazor
我有一个名为 Hello 的 JavaScript 事件:
addEventListener('hello', function () {
alert("event listener");
})
Run Code Online (Sandbox Code Playgroud)
并且,在另一个 javascript 函数中,我引发了该事件:
let event = new Event("hello", { bubbles: true });
document.dispatchEvent(event);
Run Code Online (Sandbox Code Playgroud)
我现在想做的是让事件在 javascript 函数中触发。Blazor 应该侦听事件,而不是调用 Blazor 方法的 javascript。
希望任何人都可以帮助我。
问候我,
Con*_*Low 11
对于自定义事件,您需要手动利用JavaScript/.NET 互操作性。
使用实例方法调用方法:
- 通过引用 JavaScript 传递 .NET 实例:
- 对 DotNetObjectReference.Create 进行静态调用。
- 将实例包装在 DotNetObjectReference 实例中,并在 DotNetObjectReference 实例上调用 Create。处理 DotNetObjectReference 对象(本节后面将提供一个示例)。
invokeMethod
使用或函数调用实例上的 .NET 实例方法invokeMethodAsync
。从 JavaScript 调用其他 .NET 方法时,.NET 实例也可以作为参数传递。
请注意,这是一个非常简化的示例。您可能想添加一些东西;IDisposable
从互操作类开始以避免内存泄漏。
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();
}
}
Run Code Online (Sandbox Code Playgroud)
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
}
Run Code Online (Sandbox Code Playgroud)
DotNetObjectReference
,并且可以在 C# 中调用互操作:function addCustomEventListener(dotNetObjectRef) {
document.addEventListener('hello', (event) => {
// Calls a method by name with the [JSInokable] attribute (above)
dotNetObjectRef.invokeMethodAsync('OnCustomEvent')
});
}
Run Code Online (Sandbox Code Playgroud)
如果使用 TypeScript,您可以查看此GitHub Issue。
Pou*_*tor 10
对于任何想知道 @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; }
}
Run Code Online (Sandbox Code Playgroud)
./wwwroot/index.html
在里面和之后添加JS <script src="_framework/blazor.webview.js" autostart="false"></script>
:
<script>
Blazor.registerCustomEventType('cityclicked', {
createEventArgs: event => {
return {
id: event.detail
};
}
});
</script>
Run Code Online (Sandbox Code Playgroud)
在你的剃须刀中:
@code {
private void HandleCityClicked(CustomSelectionCityEventArgs eventArgs)
{
Console.WriteLine("Bouep");
}
}
<div id="CarteLeaflet" @oncityclicked="HandleCityClicked"></div>
Run Code Online (Sandbox Code Playgroud)
最后在 JS 中你可以调度事件:
function OnMarkerClick(pId) {
const event = new CustomEvent('cityclicked', {
bubbles: true,
detail: pId
});
document.getElementById('CarteLeaflet').dispatchEvent(event);
}
Run Code Online (Sandbox Code Playgroud)
不要犯和我一样的错误,C#中的事件名称应该以“on”开头(JS:“cityclicked”,C#:“oncityclicked”)。
归档时间: |
|
查看次数: |
14447 次 |
最近记录: |