将行数据向下传递到Grid中的子单元格组件,而不作为参数传递



我已经建立了一个简单的网格组件,大部分工作,但是我遇到了一种情况,我需要传递griddrow的实例被渲染到GridCell,以允许GridCell组件访问它的属性,并在必要时修改。

组件由Grid, GridBody和GridCell 3部分组成,如下所示:

在index.razor中的用法

<Grid Items="MyItems">
<GridBody Context="row">
<GridCell>@row.Id</GridCell>
<GridCell>@row.Item.Description</GridCell>
</GridBody>
</Grid>

Grid.razor:

@namespace Accounting.Web.Components
@typeparam TItem
@attribute [CascadingTypeParameter(nameof(TItem))];
<CascadingValue Value="this" IsFixed="true">
<table cellspacing="0">
<tbody>
@foreach (var row in Rows)
{
<tr>
@GridBody(row)
</tr>
}
</tbody>
</table>
</CascadingValue>

Grid.razor.cs

namespace Accounting.Web.Components
{
public class GridRow<TItem>
{
public TItem Item { get; set; } = default!;
public int Id { get; set; } = default!;
}
public partial class Grid<TItem>
{
[Parameter]
public RenderFragment<GridRow<TItem>> GridBody { get; set; } = default!;
[Parameter]
public IList<TItem> Items { get; set; } = default!;
}
}

GridBody.razor

@namespace Accounting.Web.Components
@typeparam GridRow
GridBody.razor.cs
using Microsoft.AspNetCore.Components;
namespace Accounting.Web.Components
{
public partial class GridBody<GridRow>
{
[Parameter]
public RenderFragment<GridRow> ChildContent { get; set; }
}
}

GridCell.razor

@namespace Accounting.Web.Components
@typeparam TItem
<td>
@ChildContent
</td>

GridCell.razor.cs

using Microsoft.AspNetCore.Components;
namespace Accounting.Web.Components
{
public partial class GridCell<TItem>
{
[CascadingParameter]
public Grid<TItem> Grid { get; set; } = default!;
[Parameter]
public int Id { get; set; } = default!;
[Parameter]
public GridRow<TItem> Row { get; set; } = default!;
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
}
}

在我的各种尝试中,我试图将行从GridBody传递到GridCell,但没有任何东西接近工作。我可以完成我需要的唯一方法是直接将row作为参数传递到index中的标记中。剃刀如下:

<GridCell Row=row>@row.Id</GridCell>

这意味着我需要在每个GridCell中传递它。有没有更优雅的传递行到GridCell上面没有使用参数?

解决方案很简单,只需使用一个级联值组件到Grid.razor:

Grid.razor:

@namespace Accounting.Web.Components
@typeparam TItem
@attribute [CascadingTypeParameter(nameof(TItem))];
<CascadingValue Value="this" IsFixed="true">
<table cellspacing="0">
<tbody>
@foreach (var row in Rows)
{
<tr>
<CascadingValue Value="row">
@GridBody(row)
</CascadingValue>
</tr>
}
</tbody>
</table>
</CascadingValue>

GridCell.razor

@namespace Accounting.Web.Components
@typeparam TItem
<td>
@ChildContent
</td>

GridCell.razor.cs

using Microsoft.AspNetCore.Components;
namespace Accounting.Web.Components
{
public partial class GridCell<TItem>
{
[CascadingParameter]
public Grid<TItem> Grid { get; set; } = default!;
[Parameter]
public int Id { get; set; } = default!;
[CascadingParameter]
public GridRow<TItem> Row { get; set; } = default!;
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
}
}

相关内容

最新更新