简体   繁体   English

如何在 blazor 中使用多种类型的通用组件

[英]how to use generic components with multiple types in blazor

I'm making a generic grid component in blazor c# to handle CRUD operations and master detail relations.我正在 blazor c# 中制作一个通用网格组件来处理 CRUD 操作和主细节关系。

now I have two generic components现在我有两个通用组件

public class GridM<TParentModel> where TParentModel : new() { // My code }

and I have我有

public class GridD<TParentModel,TChildModel> : GridM<TChildModel>where TParentModel : new() 
{

 // here I'm overriding some methods from the parent class to handle relational stuff

}

so for plain tables I'm using GridM to display my data and when I have 1 to many relations with the master table I'm using GridD to display the relational data.所以对于普通表,我使用 GridM 来显示我的数据,当我与主表有一对多关系时,我使用 GridD 来显示关系数据。

so far so good, I do not have any issues with the above approach.到目前为止一切顺利,我对上述方法没有任何问题。 Then after putting some thoughts on this approach I've decided to merge GridM and GridD into one class like this:然后在对这种方法进行了一些思考之后,我决定将 GridM 和 GridD 合并到一个 class 中,如下所示:

public class MyGrid<TModel> {}
public class MyGrid<TModel, TChild> : MyGrid<TChild>{ // and override methods here }

this in theory works fine and assuming these implementations were not components I would be able to initialize them like这在理论上可以正常工作,并且假设这些实现不是组件,我将能够像这样初始化它们

 var a = new MyGrid<Users>();
 var b = new MyGrid<Users,Orders>();

so when I try to use this component like所以当我尝试使用这个组件时

< MyGrid TModel="UserModel"> </MyGrid >

I get the following error:我收到以下错误:

The component 'MyGrid' is missing required type arguments.组件“MyGrid”缺少必需的类型 arguments。 Specify the missing types using the attributes: 'TChildModel'.使用属性指定缺少的类型:“TChildModel”。

because blazor does not now whether I'm using MyGrid<TModel> or MyGrid<TModel,TChildModel> .因为 blazor 现在不使用MyGrid<TModel>还是MyGrid<TModel,TChildModel>

my question is how can I make blazor understand this?我的问题是如何让 blazor 明白这一点?

You don't have one class, you have two.你没有一个 class,你有两个。 The Razor compiler doesn't know which class to map the Tag to, so it throws the error: Razor 编译器不知道哪个 class 到 map 标签到,所以它抛出错误:

Multiple components use the tag Fred. Components: SO73613449.Data.Fred<TModel>, SO73613449.Data.Fred<TModel, TType>

You can't use them directly in Razor markup, but you can in RenderTreeBuilder code in a RenderFragment .您不能直接在 Razor 标记中使用它们,但您可以在RenderFragment中的RenderTreeBuilder代码中使用它们。

Here's some code to demo how to do it:这里有一些代码来演示如何做到这一点:

First my classes:首先我的课:

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;

namespace SO73613449.Data;

public class Fred<TModel> : ComponentBase
{
    public TModel? Model { get; set; }
    protected string name = "Fred (TModel)";
    protected string cssClass = "alert alert-primary";

    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        builder.OpenElement(0, "div");
        builder.AddAttribute(1, "class", cssClass);
        builder.AddMarkupContent(2, $"Hello from {name} <br /> {this.GetType().FullName}");
        builder.CloseElement();
    }
}

public class Fred<TModel, TType> : Fred<TModel>
{
    public TType? Type { get; set; }

    public Fred()
    {
        name = "Fred(TModel, TType)";
        cssClass = "alert alert-dark";
    }
}

And then a demo page:然后是演示页面:

@page "/"
@using Microsoft.AspNetCore.Components.Rendering;
@using SO73613449.Data;

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

@TestFirst

@TestSecond

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

@code {
    private RenderFragment TestFirst => __builder =>
        {
            __builder.OpenComponent<Fred<int>>(0);
            __builder.CloseComponent();
        };

    private RenderFragment TestSecond => __builder =>
        {
            __builder.OpenComponent<Fred<int, string>>(0);
            __builder.CloseComponent();
        };
}

And here's what it looks like:这就是它的样子:

在此处输入图像描述

The alternative is to just give them two names!另一种方法是只给他们两个名字!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM