在Blazor中使用组件时,我经常需要子组件对参数更改值做出反应,并相应地采取措施。
在一个简单的例子中,我有一个UserId参数链接在父组件和子组件之间。其思想是,当父级更改UserId值时,子级中的属性setter会调用一个读取所需数据的方法。下面是一些代码进行说明。
MyParent:
<ChildComponent UserId="@UserId" />
<a onclick="@ChangeUser">Load User</a>
@code
{
public int UserId = 0;
void ChangeUser()
{
UserId = 1;
}
}
子组件:
@if(userDetails != null)
{
<div>First Name: @userDetails.FirstName</div>
<div>Surname: @userDetails.Surname</div>
}
@code
{
private int _userId;
[Parameter] public int UserId
{
get => _userId;
set
{
_userId = value;
LoadUserDetails();
}
}
UserDetails userDetails;
async Task LoadUserDetails()
{
userDetails = [read from server here];
StateHasChanged();
}
}
现在,虽然这很有效,但我不太喜欢ChildComponent中的属性setter是同步的,但它正在调用异步代码(LoadUserDetails(。
更新父级中的UserId,让子级实现这一点,并在不阻塞任何线程的情况下调用异步方法作为响应,最干净的方法是什么?
@code
{
private int _userId;
private bool _userIdChanged;
[Parameter] public int UserId
{
get => _userId;
set
{
_userIdChanged = value != _userId;
_userId = value;
}
}
UserDetails userDetails;
async Task LoadUserDetails()
{
userDetails = [read from server here];
StateHasChanged();
}
protected override async Task OnParametersSetAsync()
{
await base.OnParametersSetAsync().ConfigureAwait(false);
if (_userIdChanged)
{
await LoadUserDetails().ConfigureAwait(false);
}
}
}