Hello Blazor:(11)全局截获事件执行
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hello Blazor:(11)全局截获事件执行相关的知识,希望对你有一定的参考价值。
前言
在Blazor中,我们使用@on{DOM EVENT}="{DELEGATE}"
这样的Razor语法在组件标记中指定委托事件处理程序:
<button @onclick="IncrementCount">Click me</button>
但是没有提供解除委托的方法。
比如,我们需要在某种条件下才执行事件处理:
有不有阻止事件触发的方案呢?
常规解决方案
我们可以在委托事件处理程序中加上判断:
<button @onclick="()=> { if (!checkedValue) { IncrementCount(); } }">Click me</button>
但是,如果有多个组件都需要加上这个判断,这样写感觉比较繁琐。
有不有更简化的方法?
深入分析
在前面的文章中,我们已经知道Blazor组件实际上会编译成C#语句。
在obj\\Debug\\net5.0\\Razor\\Pages目录下,可以看到@onclick="IncrementCount"
对应的代码如下:
__builder.AddAttribute(13, "onclick",
Microsoft.AspNetCore.Components.EventCallback.Factory.Create<Microsoft.AspNetCore.Components.Web.MouseEventArgs>(this, IncrementCount));
原来是创建了一个EventCallback事件回调。
在github上查找到EventCallback.Factory.Create
的实现源码[1]:
private EventCallback CreateCore(object receiver, MulticastDelegate callback)
{
return new EventCallback(callback?.Target as IHandleEvent ?? receiver as IHandleEvent, callback);
}
上面代码的意思,如果callback的来源是IHandleEvent
,则实际回调的是IHandleEvent
实现。
也就是说,只需要组件继承IHandleEvent
,那么就可以控制组件上所有的事件回调了。
实现
修改代码如下:
@implements IHandleEvent
Task IHandleEvent.HandleEventAsync(EventCallbackWorkItem callback, object arg)
{
System.Console.WriteLine("HandleEven");
return callback.InvokeAsync(arg);
}
private void IncrementCount()
{
System.Console.WriteLine("Clicked...");
currentCount++;
}
运行后可以看到,确实先执行的HandleEventAsync
,再执行的@onclick
实现:
结论
通过本文,我们可以了解到,只要在组件上继承IHandleEvent
,就可以实现全局截获事件回调。
但是,你会发现有一个问题,Current count
没有发生变化!
这是为什么呢?请听下回分解!
参考资料
[1]
实现源码: https://github.com/dotnet/aspnetcore/blob/main/src/Components/Components/src/EventCallbackFactory.cs
以上是关于Hello Blazor:(11)全局截获事件执行的主要内容,如果未能解决你的问题,请参考以下文章
从 Blazor 组件 (.razor) 重定向到 Razor 页面 (.cshtml) [服务器端]