Blazor University (6)组件 — 组件事件
原文链接:https://blazor-university.com/components/component-events/
组件事件
源代码[1]
EventCallback<T>
类是一个特殊的 Blazor 类,可以作为参数公开,以便组件可以在发生感兴趣的事情时轻松通知使用者。
一旦声明了 EventCallback<T>
类型的公共属性并使用 [Parameter]
属性进行了修饰,使用组件就可以在 Razor 标记中指定触发事件时要调用的方法。
向 Counter 组件添加事件
在新的 Blazor 应用中,编辑 /Pages/Counter.razor 文件并添加新的回调参数。
[Parameter]
public EventCallback<int> OnMultipleOfThree { get; set; }
这声明了一个名为 OnMultipleOfThree
的新 EventCallback
,任何使用组件都可以注册它。<int>
指定事件回调发出的值将是 System.Int32
。
现在,如果我们编辑 IncrementCount
方法,我们可以在计数器增加到 3 的倍数时发出此事件。
private async Task IncrementCount()
{currentCount++;if (currentCount % 3 == 0)await OnMultipleOfThree.InvokeAsync(currentCount);
}
订阅 EventCallback
编辑 /Pages/Index.razor 页面,以便我们嵌入 Counter 组件并订阅其 OnMultipleOfThree 事件。将其标记更改为以下内容。
@page "/"Last multiple of three = @LastMultipleOfThree<Counter OnMultipleOfThree=@UpdateLastMultipleOfThreeValue/>@code
{int LastMultipleOfThree = 0;private void UpdateLastMultipleOfThreeValue(int value){LastMultipleOfThree = value;}
}
第 9 行
声明一个 int 类型的类成员,它存储 3 值的最后一个倍数。
第 3 行
显示 LastMultipleOfThree 的值
第 5 行
嵌入 Counter 组件并设置其 OnMultipleOfThree 事件以在发出事件时执行 UpdateLastMultipleOfThreeValue 方法。
第 11 行
从事件接收到的值用于更新 LastMultipleOfThree 的值。
EventCallback和 .NET 事件之间的区别
单播与多播
最显着的区别是 EventCallback<T>
是单播事件处理程序,而 .NET 事件是多播。Blazor EventCallback<T>
旨在分配单个值,并且只能回调单个方法。
// Setting a Blazor EventCallback
<MyComponent SomeEvent=@MyMethodToCall/>// Setting a .NET event
MyComponent.SomeEvent += MyMethodToCall;
// Unscrubscribing from the event
MyComponent.SomeEvent -= MyMethodToCall;
类与结构
.NET 事件(委托)是类,而 Blazor EventCallback<T>
是只读结构。与 .NET 委托不同,EventCallback<T>
不能为 null,因此在发出事件时无需进行任何 null 检查。
// Invoking a .NET event
MyNetEvent?.Invoke(this, someValue);// Invoking a CallbackEvent<T>
MyEventCallback.InvokeAsync(someValue);
等待回调
标准 .NET 事件是同步的,而 Blazor EventCallback<T>
是异步的。正如我们在前面的示例代码中看到的,EventCallback<T>.InvokeAsync
返回一个可以等待的 Task
。
Razor 标记兼容性
无法使用 [Parameter]
装饰标准 .NET 事件并通过 Razor 标记设置它,而使用 EventCallback<T>
可以。这使我们能够在视图标记本身中表达事件回调,这使得开发人员的意图更容易看到。
自动状态变化检测
每当从 EventCallback<T>
调用方法时,在方法执行后,Blazor 将在使用组件上执行 StateHasChanged()
,以便在方法调用更改状态时重新渲染它。如果使用者的方法是通过标准 .NET 事件、Action或不是由 EventCallback<T>
发起的任何其他方法回调的,则不会发生这种情况。
例如,如果我们将一个新的 [Parameter]
添加到 Action<int>
类型的 Counter 组件中,并在当前计数是 2 的倍数时调用它,我们可以看到使用组件的渲染行为是如何受到影响的。
更改 Counter 组件以匹配以下代码:
@page "/counter"<h1>Counter</h1><p>Current count: @currentCount</p><button class="btn btn-primary" @onclick=IncrementCount>Click me</button>@code {private int currentCount = 0;[Parameter]public Action<int> OnMultipleOfTwoAction { get; set; }[Parameter]public EventCallback<int> OnMultipleOfThree { get; set; }private async Task IncrementCount(){currentCount++;if (currentCount % 2 == 0)OnMultipleOfTwoAction?.Invoke(currentCount);if (currentCount % 3 == 0)await OnMultipleOfThree.InvokeAsync(currentCount);}
}
第 13 行
添加了
Action<int>
类型的[Parameter]
第 21-22 行
如果当前计数是 2 的倍数,则调用
OnMultipleOfTwoAction
现在更改 Index 组件,使其在值为 2 的倍数时设置回调方法,因此它也会存储并显示从 OnMultipleOfTwoAction
接收到的最后一个数字在使用的组件上。
@page "/"<ul><li>Last multiple of two = @LastMultipleOfTwo</li><li>Last multiple of three = @LastMultipleOfThree</li>
</ul><Counter OnMultipleOfThree=@UpdateLastMultipleOfThreeValue OnMultipleOfTwoAction=@UpdateLastMultipleOfTwoValue />@code
{int LastMultipleOfTwo = 0;int LastMultipleOfThree = 0;private Task UpdateLastMultipleOfThreeValue(int value){LastMultipleOfThree = value;return Task.CompletedTask;}private void UpdateLastMultipleOfTwoValue(int value){LastMultipleOfTwo = value;}
}
第 13 行
定义一个新成员来存储从使用组件传递的最新“二的倍数”值
第 4 行
在用户界面中显示 LastMultipleOfTwo 的值
第 9 行
在使用的组件上设置
OnMultipleOfTwo
以便在当前值是 2 的倍数时通知我们的组件第 24 行
记录使用组件通知我们的最后 2 的倍数
当我们现在运行应用程序并多次单击按钮时,我们会看到当通过 Action<int>
回调 UpdateLastMultipleOfTwoValue
时,视图没有更新,但是当下一次单击通过 EventCallback<int>
回调 UpdateLastMultipleOfThreeValue
时,视图更新并显示两者的最新值。
点击计数 | 回调执行 | 使用者重新渲染 |
---|---|---|
1 | 无 | N/A |
2 |
Action<int>
|
No |
3 |
Action<int> EventCallback<int>
|
Yes |
4 |
Action<int>
|
No |
5 | None | N/A |
6 |
Action<int> EventCallback<int>
|
Yes |
EventCallback<T>
通常回调带有签名 private Task SomeName(T value)
的方法——其中方法的暴露级别并不重要。但是,Blazor 将允许我们设置一个 EventCallback<T>
来回调具有几个变体的方法。
如果我们的方法不执行任何异步操作,那么下面的实现可能会开始变得乏味:
public Task SomethingHappenedInChildComponent(string value)
{// Do something with valuereturn Task.CompletedTask;
}
因此,Blazor 将允许我们设置 EventCallback<T>
以回调具有 void
返回类型的方法。
public void SomethingHappenedInChildComponent(string value)
{// Do something with value
}
有时我们只想知道一个事件何时发生,而不是对它传递的值感兴趣。Blazor 还将回调一个排除 value 参数的方法。
// Either
public void SomethingHappenedInChildComponent()
{// Do something that doesn't need the value
}// Or
public Task SomethingHappenedInChildComponent()
{// Do some asynchronous work that doesn't need the valuereturn SomeTask;
}
浏览器 DOM 事件
呈现任何标记时,可以在呈现的 HTML 元素上分配标准 JavaScript 事件,以便执行我们自己的 Blazor C# 方法。例如,我们在其他地方的许多示例中使用了 @onclick
指令:
<button @onclick=ButtonClicked>Click me</button>
这些事件指令在 Visual Studio 编辑器中具有完整的 IntelliSense 支持,因此开始键入 @
符号应该会为我们提供可用指令的完整列表,以及标识事件在我们的事件处理程序中传递给我们的参数类类型的描述。DOM 事件以 @on
开头。
警告:在编写完全在服务器上运行的 Blazor 应用程序时,Blazor 将 hook 浏览器中的事件并将它们发送到服务器,以便可以调用我们的 C# 方法。这可能会导致频繁触发的事件(例如 onmousemove)明显变慢。
注意: 因为 C# 方法的 JavaScript 调用是异步的,这意味着在 C# 方法中我们不能像在 JavaScript 中那样取消事件。这是因为取消浏览器 DOM 事件是一个同步操作,当我们的 C# 被异步调用时,取消事件已经太迟了。
可用的 DOM 事件及其参数类型包括:
一般事件
DOM 事件 | 参数类型 |
---|---|
onactivate | EventArgs |
onbeforeactivate | EventArgs |
onbeforedeactivate | EventArgs |
ondeactivate | EventArgs |
onended | EventArgs |
onfullscreenchange | EventArgs |
onfullscreenerror | EventArgs |
onloadeddata | EventArgs |
onloadedmetadata | EventArgs |
onpointerlockchange | EventArgs |
onpointerlockerror | EventArgs |
onreadystatechange | EventArgs |
onscroll | EventArgs |
焦点事件
DOM 事件 | 参数类型 |
---|---|
onfocus | FocusEventArgs |
onblur | FocusEventArgs |
onfocusin | FocusEventArgs |
onfocusout | FocusEventArgs |
鼠标事件
DOM 事件 | 参数类型 |
---|---|
onmouseover | MouseEventArgs |
onmouseout | MouseEventArgs |
onmousemove | MouseEventArgs |
onmousedown | MouseEventArgs |
onmouseup | MouseEventArgs |
onclick | MouseEventArgs |
ondblclick | MouseEventArgs |
oncontextmenu | MouseEventArgs |
onwheel | WheelEventArgs |
onmousewheel | WheelEventArgs |
拖动事件
DOM 事件 | 参数类型 |
---|---|
ondrag | DragEventArgs |
ondragend | DragEventArgs |
ondragenter | DragEventArgs |
ondragleave | DragEventArgs |
ondragover | DragEventArgs |
ondragstart | DragEventArgs |
ondrop | DragEventArgs |
键盘事件
DOM 事件 | 参数类型 |
---|---|
onkeydown | KeyboardEventArgs |
onkeyup | KeyboardEventArgs |
onkeypress | KeyboardEventArgs |
输入事件
DOM 事件 | 参数类型 |
---|---|
onchange | ChangeEventArgs |
oninput | ChangeEventArgs |
oninvalid | EventArgs |
onreset | EventArgs |
onselect | EventArgs |
onselectstart | EventArgs |
onselectionchange | EventArgs |
onsubmit | EventArgs |
剪贴板事件
DOM 事件 | 参数类型 |
---|---|
onbeforecopy | EventArgs |
onbeforecut | EventArgs |
onbeforepaste | EventArgs |
oncopy | ClipboardEventArgs |
oncut | ClipboardEventArgs |
onpaste | ClipboardEventArgs |
触摸事件
DOM 事件 | 参数类型 |
---|---|
ontouchcancel | TouchEventArgs |
ontouchend | TouchEventArgs |
ontouchmove | TouchEventArgs |
ontouchstart | TouchEventArgs |
ontouchenter | TouchEventArgs |
ontouchleave | TouchEventArgs |
指针事件
DOM 事件 | 参数类型 |
---|---|
ongotpointercapture | PointerEventArgs |
onlostpointercapture | PointerEventArgs |
onpointercancel | PointerEventArgs |
onpointerdown | PointerEventArgs |
onpointerenter | PointerEventArgs |
onpointerleave | PointerEventArgs |
onpointermove | PointerEventArgs |
onpointerout | PointerEventArgs |
onpointerover | PointerEventArgs |
onpointerup | PointerEventArgs |
多媒体事件
DOM 事件 | 参数类型 |
---|---|
oncanplay | EventArgs |
oncanplaythrough | EventArgs |
oncuechange | EventArgs |
ondurationchange | EventArgs |
onemptied | EventArgs |
onpause | EventArgs |
onplay | EventArgs |
onplaying | EventArgs |
onratechange | EventArgs |
onseeked | EventArgs |
onseeking | EventArgs |
onstalled | EventArgs |
onstop | EventArgs |
onsuspend | EventArgs |
ontimeupdate | EventArgs |
onvolumechange | EventArgs |
onwaiting | EventArgs |
进度事件
DOM 事件 | 参数类型 |
---|---|
onloadstart | ProgressEventArgs |
ontimeout | ProgressEventArgs |
onabort | ProgressEventArgs |
onload | ProgressEventArgs |
onloadend | ProgressEventArgs |
onprogress | ProgressEventArgs |
onerror | ErrorEventArgs |
参考资料
[1]
源代码: https://github.com/mrpmorris/blazor-university/tree/master/src/Components/EventCallbacks
Blazor University (6)组件 — 组件事件相关推荐
- Blazor University (5)组件 — 字面量、表达式和指令
原文链接:https://blazor-university.com/components/literals-expressions-and-directives/ 字面量.表达式和指令 源代码[1] ...
- 如何用 Blazor 实现 Ant Design 组件库(二)
前言 前两周,我发表了上一篇文章<如何用 Blazor 实现 Ant Design 组件库?>,得到了很多朋友的响应,也有很多朋友加入我的钉钉群,并收听了我在第二天的直播. 这次直播是我人 ...
- 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 获取要注入事件的 View 对象 | 通过反射获取 View 组件的事件设置方法 )
文章目录 前言 一.获取要注入事件的 View 对象 二.通过反射获取 View 组件的事件设置方法并执行 前言 Android 依赖注入的核心就是通过反射获取 类 / 方法 / 字段 上的注解 , ...
- php事件和行为,Yii框架组件和事件行为管理详解
Yii框架组件和事件行为管理详解 来源:中文源码网 浏览: 次 日期:2018年9月2日 [下载文档: Yii框架组件和事件行为管理详解.txt ] (友情提示:右键点上行txt文档名- ...
- angular2子组件的事件传递(任意组件事件传递)
angular2子组件的事件传递 angular2有很多组件组成,画面由很多路由,导致事件的传递很"笨拙",本组的技术负责人发现了任意组件传递事件的这个方法,教会了我,我做个笔记. ...
- 如何用 Blazor 实现 Ant Design 组件库?
本文主要分享我创建 Ant Design of Blazor 项目的心路历程,已经文末有一个 Blazor 线上分享预告. Blazor WebAssembly 来了! Blazor 这个新推出的前端 ...
- 七、功能性组件与事件逻辑(IVX 快速开发教程)
七.功能性组件与事件逻辑 由于 iVX 极度易用的特性,在 iVX 中开发微信小程序.WebApp.小游戏应用的开发流程大致相同.介绍完基础可视化组件后通过后台的服务.数据库与事件结合即可完成一个应用 ...
- angular移除事件绑定事件绑定_Vue.js子组件利用事件向父组件传输数据,以及sync修饰符和双向绑定...
在Vue.js的组件中,prop是"单向绑定"的,数据只能从父组件传输到子组件.Vue文档中的说了这样做的原因: 所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑 ...
- 组件:参数验证、组件:事件传递
组件:参数验证 知识点 props:组件参数验证语法 组件的数据 为组件中接受到的变量进行逻辑验证. 综合例 <div id="myApp"><h1>身世之 ...
最新文章
- 利用mysql建立随机森林_随机森林算法实例 - osc_4imme0wh的个人空间 - OSCHINA - 中文开源技术交流社区...
- C++/C++11中std::runtime_error的使用
- 2020 互联网应届硕士的薪资情况
- [转]TortoiseSVN客户端重新设置用户名和密码
- lambda捕获this_非捕获Lambda的实例
- android退出app代码,Android应用退出代码各种方式
- PHP ceil()函数
- UVA 11806 Cheerleaders (容斥原理)
- SharpGL中Finish和Flush的区别
- 机器人把大龙拉出来_LOL-LPL夏季赛:Wei男枪打野未换惩戒 ES让BLG拿下首胜
- JavaScript中字符串的match与replace方法
- SPOJ REPEATS Repeats (后缀数组 + RMQ:子串的最大循环节)题解
- java基于http协议编程_网络传输协议(http协议)
- IE浏览器的一些技巧
- 中科图新BIM+GIS数字化设计施工管理解决方案
- 利用css伪类元素实现点击范围扩大
- 如何使用cookie信息,完成自动登录
- 诱饵扫描_这是标题点击诱饵吗
- 中国证券市场的发展历程
- AD绘图中遇到的问题(集)
热门文章
- jQuery 基金会和 Dojo 基金会合并:Open Web
- python 中 __name__ 的使用
- javascript中Date对象的初始化方法
- CentOS 5.5 Freeradius MySQL
- ajax使用html()后样式无效,jquery.ajax使用字符串拼接后内联css样式失效
- ping -a 获取不到主机名_网络测试命令——PING
- wpf: DataGridTextColumn 数字格式显示,编辑时取消格式(StringFormat)
- jmete 学习--基础之名词解释
- allegro下快捷键设置[转贴]
- Oracle免客户端InstantClient安装使用