CssBuilder 包的 Blazor 属性问题

Blazor attribute splatting issues with CssBuilder package

我正在使用 CssBuilder to build the CSS as described in CssBuilder docs。当我添加它时,它又会破坏我传递的点击处理程序。我要么获得点击处理程序,要么获得 CSS,但不能同时获得。

ComponentUIBase

using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;

namespace BlazorServer.UI
{
    public class UIComponentBase : ComponentBase
    {

        [Parameter]
        public RenderFragment ChildContent { get; set; }

        [Parameter(CaptureUnmatchedValues = true)]
        public IReadOnlyDictionary<string, object> AdditionalAttributes { get; set; } = new Dictionary<string, Object>();

    }
}

自定义 Button.razor 组件 - 当 @attributes 存在时,CSS 中断并且 onclick 起作用,当删除 @attributes 时,CSS 起作用并且 onclick 中断

@inherits UIComponentBase

<button class="@BaseCss" @attributes="AdditionalAttributes">
    @ChildContent
</button>

自定义Button.cs代码隐藏

using BlazorComponentUtilities;
using Microsoft.AspNetCore.Components;

namespace BlazorServer.UI.Buttons
{
    public partial class Button
    {

        [Parameter]
        public string Color { get; set; } = "btn-primary";

        [Parameter]
        public bool Rounded { get; set; } = false;

        public string BaseCss =>
           new CssBuilder("btn")
            .AddClass(Color)
            .AddClass("rounded-0", when: !Rounded)
            .AddClass("rounded-2", when: Rounded)
            .AddClass("shadow-none")
            .AddClassFromAttributes(AdditionalAttributes)
            .Build();
    }
}

父组件

    <Card Color="bg-info">
        <CardHeader>Card Header</CardHeader>
        <CardBody>
            <CardTitle>Card title</CardTitle>
            <CardTitle SubTitle>Card Subtitle</CardTitle>
            <CardText>Card text goes here...</CardText>
        </CardBody>
        <CardFooter>
            <Spacer />
            <Button Color="bg-danger">Cancel</Button>
            <Button class="ms-2" Color="bg-primary" @onclick="Test">Ok</Button>
        </CardFooter>
    </Card>

@code {
    private async void Test()
    {

        await JsRuntime.InvokeVoidAsync("alert", "Warning!11"); // Alert
    }
}

您需要从飞溅属性中删除 class

我的设置和你类似。这是一些代码。

我的UIComponentBase:

public abstract class UIComponentBase : ComponentBase
{
    [Parameter] public RenderFragment? ChildContent { get; set; }

    [Parameter(CaptureUnmatchedValues = true)] public IDictionary<string, object> UserAttributes { get; set; } = new Dictionary<string, object>();

    protected virtual List<string> UnwantedAttributes { get; set; } = new List<string>();

    protected Dictionary<string, object> SplatterAttributes
    {
        get
        {
            var list = new Dictionary<string, object>();
            foreach (var item in UserAttributes)
            {
                if (!UnwantedAttributes.Any(item1 => item1.Equals(item.Key)))
                    list.Add(item.Key, item.Value);
            }
            return list;
        }
    }
}

我的基地 class - 默认 div:

public class UIComponent : UIComponentBase
{

    [Parameter] public bool Show { get; set; } = true;

    [Parameter] public bool Disabled { get; set; } = false;

    [Parameter] public string? Tag { get; set; }

    [Parameter] public EventCallback<MouseEventArgs> ClickEvent { get; set; }

    protected virtual List<string> CssClasses { get; private set; } = new List<string>();

    protected virtual string HtmlTag => this.Tag ?? "div";

    protected override List<string> UnwantedAttributes { get; set; } = new List<string>() { "class" };

    protected string CssClass
        => CSSBuilder.Class()
            .AddClass(CssClasses)
            .AddClassFromAttributes(this.UserAttributes)
            .Build();

    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        if (this.Show)
        {
            builder.OpenElement(0, this.HtmlTag);
            builder.AddMultipleAttributes(1, this.SplatterAttributes);
            if (!string.IsNullOrWhiteSpace(this.CssClass))
                builder.AddAttribute(2, "class", this.CssClass);

            if (Disabled)
                builder.AddAttribute(3, "disabled");

            if (ClickEvent.HasDelegate)
                builder.AddAttribute(4, "onclick", EventCallback.Factory.Create<MouseEventArgs>(this, ClickEvent));

            builder.AddContent(5, ChildContent);
            builder.CloseElement();
        }
    }
}

然后是我的按钮:

public class UIButton : UIComponent
{
    public UIButton()
        => this.CssClasses.Add("btn mr-1");

    protected override string HtmlTag => "button";

    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        if (this.Show)
        {
            builder.OpenElement(0, this.HtmlTag);
            builder.AddAttribute(1, "class", this.CssClass);
            builder.AddMultipleAttributes(2, this.SplatterAttributes);

            if (!UserAttributes.ContainsKey("type"))
                builder.AddAttribute(3, "type", "button");

            if (Disabled)
                builder.AddAttribute(4, "disabled");

            if (ClickEvent.HasDelegate)
                builder.AddAttribute(5, "onclick", EventCallback.Factory.Create<MouseEventArgs>(this, ClickEvent));

            builder.AddContent(6, ChildContent);
            builder.CloseElement();
        }
    }
}

所以我不知道 right-to-left 发生了属性飞溅。下面的代码修复了这个问题:)

<button @attributes="AdditionalAttributes" class="@BaseCss">
    @ChildContent
</button>