【问题标题】:Blazor - What is the correct way to extend another component?Blazor - 扩展另一个组件的正确方法是什么?
【发布时间】:2022-12-04 02:48:52
【问题描述】:
我正在使用 MudBlazor 组件库。为了在表单按钮上显示加载,documentation 像这样引导:
<MudButton Disabled="@_processing" OnClick="ProcessSomething" Variant="Variant.Filled" Color="Color.Primary">
@if (_processing)
{
<MudProgressCircular Class="ms-n1" Size="Size.Small" Indeterminate="true"/>
<MudText Class="ms-2">Processing</MudText>
}
else
{
<MudText>Click me</MudText>
}
</MudButton>
现在因为我经常这样做,所以我想将这个逻辑包装在另一个组件中。
以下组件不做这项工作:
@inherits MudButton
@code {
bool _loading;
[Parameter]
public bool Loading
{
get => _loading;
set
{
_loading = value;
Disabled = value;
}
}
[Parameter]
public new RenderFragment ChildContent
{
get => base.ChildContent;
set => base.ChildContent = ExtendContent(value);
}
private RenderFragment ExtendContent(RenderFragment baseContent) => __builder =>
{
if (Loading)
{
<MudProgressCircular Class="ms-n2" Size="Size.Small" Indeterminate="true" />
}
@baseContent
};
}
我收到此错误:
类型“<my_component>”声明了多个参数匹配
名称“儿童内容”。参数名称不区分大小写,必须
是独一无二的。
【问题讨论】:
标签:
blazor
blazor-webassembly
razor-components
【解决方案1】:
MudButton已有ChildContent参数,
你不需要继承它,
我认为您只需要在新组件中使用它
【解决方案2】:
MudBlazor 的组件库继承自 ComponentBase,它并不是真正为 Razor 继承而设计的。您正在尝试用您自己的标记替换 ChildContent。
您需要从基本组件中提取标记内容,希望没有使用私有内容,然后将其复制到子标记中。
这是我继承的组件:
@inherits MudButton
@using MudBlazor.Extensions
<MudElement @bind-Ref="@_elementReference"
HtmlTag="@HtmlTag"
Class="@Classname"
Style="@Style"
@attributes="UserAttributes"
@onclick="OnClickHandler"
type="@ButtonType.ToDescriptionString()"
href="@Href"
target="@Target"
rel="@(Target=="_blank"?"noopener":null)"
disabled="@Disabled">
<span class="mud-button-label">
@if (!string.IsNullOrWhiteSpace(StartIcon))
{
<span class="@StartIconClass">
<MudIcon Icon="@StartIcon" Size="@Size" Color="@IconColor" />
</span>
}
@if (this.Loading)
{
<MudProgressCircular Class="ms-n1" Size="Size.Small" Indeterminate="true" />
<MudText Class="ms-2">Processing</MudText>
}
else
{
<MudText>@ChildContent</MudText>
}
@if (!string.IsNullOrWhiteSpace(@EndIcon))
{
<span class="@EndIconClass">
<MudIcon Icon="@EndIcon" Size="@Size" Color="@IconColor" />
</span>
}
</span>
</MudElement>
@code {
[Parameter] public bool Loading { get; set; }
}
代码来自此处的 MubBlazor Github 存储库 - https://github.com/MudBlazor/MudBlazor/blob/dev/src/MudBlazor/Components/Button/MudButton.razor。
我的演示页面:
@page "/"
<PageTitle>Index</PageTitle>
<MudText Typo="Typo.h3" GutterBottom="true">Hello, world!</MudText>
<MudText Class="mb-8">Welcome to your new app, powered by MudBlazor!</MudText>
<MudAlert Severity="Severity.Normal">You can find documentation and examples on our website here: <MudLink Href="https://mudblazor.com" Typo="Typo.body2" Color="Color.Inherit"><b>www.mudblazor.com</b></MudLink></MudAlert>
<MudText class="mt-6">
<MudButton Disabled="@_processing" OnClick="ProcessSomething" Variant="Variant.Filled" Color="Color.Primary">
@if (_processing)
{
<MudProgressCircular Class="ms-n1" Size="Size.Small" Indeterminate="true" />
<MudText Class="ms-2">Processing</MudText>
}
else
{
<MudText>Click me</MudText>
}
</MudButton>
<MyButton Loading=_processing Disabled="@_processing" OnClick="ProcessSomething" Variant="Variant.Filled" Color="Color.Primary">
Hello
</MyButton>
</MudText>
@code {
private bool _processing;
private async Task ProcessSomething()
{
_processing = true;
await Task.Delay(5000);
_processing = false;
}
}