1. 环境
- VS2019 16.5.1
- .NET Core SDK 3.1.200
- Blazor webAssembly Templates 3.2.0-preview2.20160.5
2. 默认绑定
2.1. 使用方法
Blazor 中 Razor 组件通过一个名为 @bind 的 html 元素属性提供数据绑定功能, 数据绑定的对象可以为字段, 属性或表达式值. 例如:
- <input @bind="_bindValue1" />
- @code{
- private int _bindValue1 { get; set; } = 1;
- }
@bind 默认绑定的是元素的 onchange 事件, 通过在组件中添加一个元素 p 可以看出效果, 每当 input 离开 focus 或者回车时, p 中的值才会更新:
<p>@_bindValue1</p>
2.2. 等价单向绑定
由于 @bind 绑定的数据是强类型, 在从 input 的 value 到绑定的数据时, 会做相关的数据转换, 如果转换失败, 则会保持上次的值不变. 也就是说, 默认绑定类似于以下代码:
<input value="@_bindValue1" @onchange="(e) => { _bindValue1 = int.TryParse(e.Value.ToString(), out var val) ? val : _bindValue1;}" />
之所以说是类似, 是因为当无法转换时, 例如输入的是小数 123.1, 当触发 onchange 事件时, 通过 @bind 绑定数据时, input 中 value 会变回上一次的整数; 而这种单向绑定时, input 的 value 显示的依然为 123.1, 不过通过 C# 获取_bindValue1 的值时, 得到的与通过 @bind 绑定数据时的行为是一致的. 在单向绑定时, 即使使用 StateHasChanged(), 由于渲染引擎未发现状态的变化, 依然是不会改变显示的值.
3. 字符串格化
@bind 可以使用 @bind:format 指定字符串的格式化表达式, 个人觉得此功能有些鸡肋, 其支持的格式表达式较为有限, 而且还具有一些其他的问题, 不知道是 bug 还是本身就这样设计的, 我目前已经在 AspNetApiDocs 提交了相关的反馈.
4. 修改默认绑定事件
在有些时候, 我们可能需要实时响应 input 中的输入内容, 例如搜索提示, 这个时候需要相应 input 的 oninput 事件,@bind 通过指定 event 参数来在指定绑定属性或字段响应的事件, 其形式为 @bind:event="eventName", 例如:
<input @bind="_bindValue2" @bind:event="oninput" />
5. 组件间的事件绑定
5.1. 父组件到子组件
通过使用 @bind-{PROPERTY} 的形式, 可以将属性值从父组件向下绑定到子组件, 其中 PROPERTY 必须为组件参数, 例如在子组件中添加一个 DateTime 参数, 要想使用 @bind 为此子组件在父组件中绑定数据, 按照约定还必须定义一个名为事件 {PROPERTY}Changed 的事件, 这个事件用于响应当子组件中更改组件参数时, 子组件对数据的回调. 代码如下:
- <input @bind="DateTime" @bind:format="yyyy-MM-dd HH:mm:ss" />
- <p>
- @DateTime.ToString("o")
- </p>
- [Parameter] public DateTime DateTime { get; set; } = DateTime.Now; [Parameter]
- public EventCallback
- <DateTime>
- DateTimeChanged { get; set; }
这样就可以在父组件中使用如下代码进行数据绑定了:
<Component @bind-DateTime="_dateTime" />
这行代码实际上等价于以下代码:
<Component @bind-DateTime="_dateTime" @bind- DateTime:event="DateTime Changed"/>
因此我们可以自定义上述约定中的默认事件 {PROPERTY}Changed 的名称, 现在效果如下 (请注意, 此时如果子组件更新的参数, 数据是无法流向父组件的):
5.2. 子组件到父组件
通常, 参数流是从上往下的, 即从父组件流到子组件, 这是与渲染流程是保持一致的. 因此当父组件更新子组件的组件参数时, 往往子组件会很容易的进行渲染, 但是当子组件向父组件传递数据, 则必须使用相应的回调事件. 这种限制是组件设计必然结果.@bind 在组件间进行数据的双向绑定正式通过在 5.1. 中的所介绍的 {PROPERTY}Changed 事件来向父组件进行数据的传递的.
首先, 在之前组件间事件绑定的代码上为 input 的 oninput 事件添加响应函数 ChangeParentValue:
- private async Task ChangeParentValue(ChangeEventArgs e)
- {
- var dateStr = e.Value.ToString();
- await DateTimeChanged.InvokeAsync(DateTime.Parse(dateStr));
- }
注意, 在这里代码并没有直接更改本组件中的组件参数 DateTime, 因为父组件中更改了状态后, 会将该数据传递到子组件, 子组件会重新渲染. 按照微软官方的代码, 这个是可以更改本组件中的组件参数 DateTime 的. 现在, 效果如下:
代码: LearningBlazor
本文参考: ASP.NET Core Blazor 数据绑定
来源: https://www.cnblogs.com/zxyao/p/12664746.html