Blazor是否支持渲染组件输出与基本组件输出合并?

时间:2019-07-23 03:56:43

标签: inheritance components render blazor

我正在创建一个图表库,该库将使用SVG输出图表。我已经能够使用@inherits创建从Chart组件继承的BarChart组件。我想在基本Chart组件中使用剃刀标记和数据绑定来呈现轴,标题,图例等,然后让BarChart组件使用剃刀标记来呈现条形图和其他特定于Barchart的东西。这可能吗?我可以在Chart和BarChart中看到如何覆盖BuildRenderTree,但是希望避免编写该较低级别的代码。

这是我使用BuildRenderTree实现的方法...

课程文件:

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.RenderTree;

namespace TangoZulu.Shared
{
    public class Chart : ComponentBase
    {
        [Parameter]
        public double Height { get; set; }
        [Parameter]
        public double Width { get; set; }
        [Parameter]
        public double BorderMargin { get; set; }
        [Parameter]
        public string BackgroundColor { get; set; }
        protected int OpenChartElement(int sequence, RenderTreeBuilder builder)
        {
            builder.OpenElement(sequence++, "svg");
            builder.AddAttribute(sequence++, "height", Height);
            builder.AddAttribute(sequence++, "width", Width);

            builder.OpenElement(sequence++, "g");

            builder.OpenElement(sequence++, "rect");  //border
            builder.AddAttribute(sequence++, "height", Height - BorderMargin);
            builder.AddAttribute(sequence++, "width", Width - BorderMargin);
            builder.AddAttribute(sequence++, "y", BorderMargin);
            builder.AddAttribute(sequence++, "x", BorderMargin);
            builder.AddAttribute(sequence++, "fill", BackgroundColor);
            builder.AddAttribute(sequence++, "stroke", "black");
            builder.CloseElement(); //border
            return sequence;
        }
        protected void CloseChartElement(RenderTreeBuilder builder)
        {
            builder.CloseElement(); //g
            builder.CloseElement(); //svg
        }
    }

    public class BarChart : Chart
    {
        [Parameter]
        public double ExampleDataX { get; set; }
        [Parameter]
        public double ExampleDataY { get; set; }
        protected override void BuildRenderTree(Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder)
        {
            int sequence = OpenChartElement(0, builder);

            builder.OpenElement(sequence++, "rect");
            builder.AddAttribute(sequence++, "height", "20");
            builder.AddAttribute(sequence++, "width", "20");
            builder.AddAttribute(sequence++, "x", ExampleDataX);
            builder.AddAttribute(sequence++, "y", ExampleDataY);
            builder.AddAttribute(sequence++, "fill", "red");
            builder.AddAttribute(sequence++, "stroke", "red");
            builder.CloseElement(); //rect            

            CloseChartElement(builder);
        }
    }

    public class PieChart : Chart
    {
        [Parameter]
        public double ExampleDataX { get; set; }
        [Parameter]
        public double ExampleDataY { get; set; }
        [Parameter]
        public double ExampleDataRadius { get; set; }
        protected override void BuildRenderTree(Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder)
        {
            int sequence = OpenChartElement(0, builder);

            builder.OpenElement(sequence++, "circle");
            builder.AddAttribute(sequence++, "cx", ExampleDataX);
            builder.AddAttribute(sequence++, "cy", ExampleDataY);
            builder.AddAttribute(sequence++, "r", ExampleDataRadius);
            builder.AddAttribute(sequence++, "fill", "blue");
            builder.AddAttribute(sequence++, "stroke", "blue");
            builder.AddAttribute(sequence++, "stroke-width", "2");
            builder.CloseElement(); //circle

            CloseChartElement(builder);
        }
    }
}

页面文件:

@using TangoZulu.Shared
@page "/"

<BarChart height="600" width="700" borderMargin="10" backgroundColor="yellow" ExampleDataX="30" ExampleDataY="40" />
<PieChart height="500" width="600" borderMargin="20" backgroundColor="grey" ExampleDataX="40" ExampleDataY="50" ExampleDataRadius="14" />

1 个答案:

答案 0 :(得分:0)

  

我可以在两个图表中看到如何覆盖BuildRenderTree   和BarChart,但希望避免编写该较低级别的代码

欢迎使用Blazor组件模型。您的主张可能被证明是错误的。建议您阅读以下内容,以快速了解您可能会遇到的问题:

我认为创建父组件和子组件可能会提供您想要的功能。创建一个父组件BarChart和一个子组件Chart。子组件应该嵌套在父组件中,并且可以从父组件中获取值,例如:子组件定义名为Title的参数属性,该属性由父组件以Component Parameter的形式提供。当然,传递的Title值将显示在子组件的视图部分的某处,也许像这样:

<div id="mychart">@Title</div>  

子组件可以具有RenderFragment委托类型的参数属性,该参数属性从父组件传递,然后从子组件调用。我们在这里定义模板化组件吗?是的,我们是的。使用模板化的组件...

我希望你能得到图片...

您可以使用您认为有用的任何方法,包括覆盖BuildRenderTree,但我的印象是Blazor团队建议采用Razor。

顺便说一句,我想您正在尝试的目的是为了学习动摇的目的,因为如果不是,则最好搜索社区完成的实现。关于绘制包括SVG在内的各种图表有很多回购。

希望这会有所帮助。