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 时,视图更新并显示两者的最新值。

f6ebba166e02608036957dedfeb38d3a.gif

事件顺序
点击计数回调执行使用者重新渲染
1N/A
2Action<int>No
3Action<int> EventCallback<int>Yes
4Action<int>No
5NoneN/A
6Action<int>  EventCallback<int>Yes

EventCallback<T> 通常回调带有签名 private Task SomeName(T value)的方法——其中方法的暴露级别并不重要。但是,Blazor 将允许我们设置一个 EventCallback<T> 来回调具有几个变体的方法。

如果我们的方法不执行任何异步操作,那么下面的实现可能会开始变得乏味:

public Task SomethingHappenedInChildComponent(string value)
{
  // Do something with value
  return 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 value
  return SomeTask;
}

浏览器 DOM 事件

呈现任何标记时,可以在呈现的 HTML 元素上分配标准 JavaScript 事件,以便执行我们自己的 Blazor C# 方法。例如,我们在其他地方的许多示例中使用了 @onclick 指令:

<button @onclick=ButtonClicked>Click me</button>

这些事件指令在 Visual Studio 编辑器中具有完整的 IntelliSense 支持,因此开始键入 @ 符号应该会为我们提供可用指令的完整列表,以及标识事件在我们的事件处理程序中传递给我们的参数类类型的描述。DOM 事件以 @on 开头。

f9ee7433182015c46442321018f7c4e8.png

将“@onabort”属性设置为提供的字符串或委托值。委托值应为“Microsoft.AspNetCore.Components.Web.ProgressEventArgs”类型

警告:在编写完全在服务器上运行的 Blazor 应用程序时,Blazor 将 hook 浏览器中的事件并将它们发送到服务器,以便可以调用我们的 C# 方法。这可能会导致频繁触发的事件(例如 onmousemove)明显变慢。

注意: 因为 C# 方法的 JavaScript 调用是异步的,这意味着在 C# 方法中我们不能像在 JavaScript 中那样取消事件。这是因为取消浏览器 DOM 事件是一个同步操作,当我们的 C# 被异步调用时,取消事件已经太迟了。

可用的 DOM 事件及其参数类型包括:

一般事件

DOM 事件参数类型
onactivateEventArgs
onbeforeactivateEventArgs
onbeforedeactivateEventArgs
ondeactivateEventArgs
onendedEventArgs
onfullscreenchangeEventArgs
onfullscreenerrorEventArgs
onloadeddataEventArgs
onloadedmetadataEventArgs
onpointerlockchangeEventArgs
onpointerlockerrorEventArgs
onreadystatechangeEventArgs
onscrollEventArgs

焦点事件

DOM 事件参数类型
onfocusFocusEventArgs
onblurFocusEventArgs
onfocusinFocusEventArgs
onfocusoutFocusEventArgs

鼠标事件

DOM 事件参数类型
onmouseoverMouseEventArgs
onmouseoutMouseEventArgs
onmousemoveMouseEventArgs
onmousedownMouseEventArgs
onmouseupMouseEventArgs
onclickMouseEventArgs
ondblclickMouseEventArgs
oncontextmenuMouseEventArgs
onwheelWheelEventArgs
onmousewheelWheelEventArgs

拖动事件

DOM 事件参数类型
ondragDragEventArgs
ondragendDragEventArgs
ondragenterDragEventArgs
ondragleaveDragEventArgs
ondragoverDragEventArgs
ondragstartDragEventArgs
ondropDragEventArgs

键盘事件

DOM 事件参数类型
onkeydownKeyboardEventArgs
onkeyupKeyboardEventArgs
onkeypressKeyboardEventArgs

输入事件

DOM 事件参数类型
onchangeChangeEventArgs
oninputChangeEventArgs
oninvalidEventArgs
onresetEventArgs
onselectEventArgs
onselectstartEventArgs
onselectionchangeEventArgs
onsubmitEventArgs

剪贴板事件

DOM 事件参数类型
onbeforecopyEventArgs
onbeforecutEventArgs
onbeforepasteEventArgs
oncopyClipboardEventArgs
oncutClipboardEventArgs
onpasteClipboardEventArgs

触摸事件

DOM 事件参数类型
ontouchcancelTouchEventArgs
ontouchendTouchEventArgs
ontouchmoveTouchEventArgs
ontouchstartTouchEventArgs
ontouchenterTouchEventArgs
ontouchleaveTouchEventArgs

指针事件

DOM 事件参数类型
ongotpointercapturePointerEventArgs
onlostpointercapturePointerEventArgs
onpointercancelPointerEventArgs
onpointerdownPointerEventArgs
onpointerenterPointerEventArgs
onpointerleavePointerEventArgs
onpointermovePointerEventArgs
onpointeroutPointerEventArgs
onpointeroverPointerEventArgs
onpointerupPointerEventArgs

多媒体事件

DOM 事件参数类型
oncanplayEventArgs
oncanplaythroughEventArgs
oncuechangeEventArgs
ondurationchangeEventArgs
onemptiedEventArgs
onpauseEventArgs
onplayEventArgs
onplayingEventArgs
onratechangeEventArgs
onseekedEventArgs
onseekingEventArgs
onstalledEventArgs
onstopEventArgs
onsuspendEventArgs
ontimeupdateEventArgs
onvolumechangeEventArgs
onwaitingEventArgs

进度事件

DOM 事件参数类型
onloadstartProgressEventArgs
ontimeoutProgressEventArgs
onabortProgressEventArgs
onloadProgressEventArgs
onloadendProgressEventArgs
onprogressProgressEventArgs
onerrorErrorEventArgs

参考资料

[1]

源代码: https://github.com/mrpmorris/blazor-university/tree/master/src/Components/EventCallbacks

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值