Grid.razor:
@foreach (var row in Rows)
{
<tr @onclick="@(() => OnRowClick(row))">
@GridBody(row)
</tr>
}
网格.razor.cs
namespace MyApp.Web.Components.Grid
{
public class GridRow<TItem>
{
public TItem Item { get; set; } = default!;
public int Id { get; set; } = default!;
public bool Active = false;
}
public partial class Grid<TItem>
{
[Parameter]
public int PageSize { get; set; } = 100;
[Parameter]
public RenderFragment GridHeader { get; set; } = default!;
[Parameter]
public RenderFragment<GridRow<TItem>> GridBody { get; set; } = default!;
public async Task OnRowClick(GridRow<TItem> row)
{
//...
}
}
}
一切如预期。然而,Grid.razor中的以下代码行对我来说并不清楚:
<tr @onclick="@(() => OnRowClick(row))">
上面的工作,但最初我尝试了以下内容:
<tr @onclick="@(OnRowClick(row))">
如果没有lambda表达式,编译器将产生以下错误:
Argument 2: cannot convert from 'System.Threading.Tasks.Task' to 'Microsoft.AspNetCore.Components.EventCallback'
为什么这里需要一个λ函数?
使用OnRowClick(row)
时,直接调用OnRowClick
函数并将结果分配给onclick
。使用() => OnRowClick(row)
是将lambda函数分配给onclick
,以便以后可以调用它(从而调用OnRowClick
)。
将onclick
视为一个变量,以下是您在C#中看到的差异:
Task<SomeType> onclick = OnRowClick(row); // Invoked now, onclick contains the result
与。
Func<Task<SomeType>> onclick = () => OnRowClick(row); // Can be invoked later
如果不需要row
作为参数(例如@onclick=@OnRowClick
),您可以简写它,因为您将传递一个稍后可以调用的函数,而不是现在调用它。