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>
我正在使用 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>