C# 将附加数据传递到Blazor组件中的通用RenderFragment

C# 将附加数据传递到Blazor组件中的通用RenderFragment,c#,asp.net-core,generics,blazor,C#,Asp.net Core,Generics,Blazor,我有一个简单的Blazor组件,它在一个通用列表上迭代: @typeparam TItem; @foreach (var item in List) { @ElementTemplate(item); // What code should be here to pass i to the ElementTemplate???? i++; } @code { int i = 0; [Para

我有一个简单的Blazor组件,它在一个通用列表上迭代:

@typeparam TItem;

 @foreach (var item in List)
        {
            @ElementTemplate(item); // What code should be here to pass i to the ElementTemplate????
            i++;
        }

@code {
    int i = 0;


    [Parameter] public List<TItem> List { get; set; }
    [Parameter] public RenderFragment<TItem> ElementTemplate { get; set; }
  }
@typeparam-TItem;
@foreach(列表中的变量项)
{
@ElementTemplate(item);//这里应该有什么代码将i传递给ElementTemplate????
i++;
}
@代码{
int i=0;
[参数]公共列表{get;set;}
[参数]公共RenderFragment元素模板{get;set;}
}
我有另一个简单的组件,它将获得一个项和一个索引来呈现数据(Employee):

@Index@人名
@代码{
[参数]公共人物{get;set;}
[参数]公共int索引{get;set;}
}
在我的主页上,我有以下内容:

<GenericList List="employees">
    <ElementTemplate>
        <Employee Person="context" Index="?"></Employee>
    </ElementTemplate>
</GenericList>

如您所见,Employee组件需要一个索引参数,如何从GenericList组件传递索引?
在本例中,应将变量“i”传递给ElementTemplate以及通用TItem对象本身。

我发现快速/简单的方法是使用元组作为RenderFragment上下文:

@foreach (var item in List)
{
  @ElementTemplate((item,i));
  i++;
}

@code {
  int i=0;
  [Parameter] public List<TItem> List { get; set; }
  [Parameter] public RenderFragment<(TItem item, int index)> ElementTemplate { get; set; }
}
@foreach(列表中的变量项)
{
@元素模板((项目,i));
i++;
}
@代码{
int i=0;
[参数]公共列表{get;set;}
[参数]公共RenderFragment元素模板{get;set;}
}
然后您的标记变成:



如果愿意,可以在GenericList中使用实用程序类而不是元组。

我发现快速/简单的方法是使用元组作为RenderFragment上下文:

@foreach (var item in List)
{
  @ElementTemplate((item,i));
  i++;
}

@code {
  int i=0;
  [Parameter] public List<TItem> List { get; set; }
  [Parameter] public RenderFragment<(TItem item, int index)> ElementTemplate { get; set; }
}
@foreach(列表中的变量项)
{
@元素模板((项目,i));
i++;
}
@代码{
int i=0;
[参数]公共列表{get;set;}
[参数]公共RenderFragment元素模板{get;set;}
}
然后您的标记变成:



如果愿意,可以在GenericList中使用实用程序类而不是元组。

可以为上下文定义复杂类

在GenericList.razon中,定义一个类:

公共类ListContext
{
公共滴度项{get;set;}
公共int索引{get;set;}
}
并将此类用作模板的上下文类型:

[参数]
公共RenderFragment元素模板{get;set;}
然后,调用此模板时,只需创建一个新类并设置正确的参数:

@foreach(列表中的变量项)
{
@ElementTemplate(新的ListContext{Item=Item,Index=i});
i++;
}

下面是一个工作示例:

您可以为您的上下文定义一个复杂的类

在GenericList.razon中,定义一个类:

公共类ListContext
{
公共滴度项{get;set;}
公共int索引{get;set;}
}
并将此类用作模板的上下文类型:

[参数]
公共RenderFragment元素模板{get;set;}
然后,调用此模板时,只需创建一个新类并设置正确的参数:

@foreach(列表中的变量项)
{
@ElementTemplate(新的ListContext{Item=Item,Index=i});
i++;
}

下面是一个工作示例:

您不能-您明确指定
ElementTemplate
接受单个数据项。如果希望它包含多个内容,可以让它从基类继承,或者实现一个接口,并将其用作通用约束。或者,使数据项
动态
,从而失去常规的优点。您可以设置一个字典,将模型类型映射到组件以进行渲染。用它来传递列表。我扩展了
ComponentBase
对于映射的组件,
ViewComponentBase:ComponentBase
您不能-您明确指定
ElementTemplate
接受单个数据项。如果希望它包含多个内容,可以让它从基类继承,或者实现一个接口,并将其用作通用约束。或者,使数据项
动态
,从而失去常规的优点。您可以设置一个字典,将模型类型映射到组件以进行渲染。用它来传递列表。我为映射的组件扩展了
ComponentBase
ViewComponentBase:ComponentBase
@谢谢,但这不是我想要的方式。您想要实现什么?也许使用级联值从GenericList组件传递索引会起作用?@谢谢,但这不是我想要的方式。你到底想要实现什么?也许使用层叠值从GenericList组件传递索引会起作用?我喜欢元组,但不会
@key=context
或至少
@key=context.item
更好?索引与员工内容的耦合最少。假设您删除了一个项,我不想讨论这些索引int如何与数据不可靠地耦合的整个问题,只想使用可用的最快类型将
@key
隐藏在其中。但你可能是对的——这一切都取决于真实世界的内容。我喜欢元组,但不会
@key=context
或至少
@key=context.item
更好吗?索引与员工内容的耦合最少。假设您删除了一个项,我不想讨论这些索引int如何与数据不可靠地耦合的整个问题,只想使用可用的最快类型将
@key
隐藏在其中。但你可能是对的——这完全取决于真实世界的内容。