我最近开始使用Blazor,发现它是一项非常有前途的技术。
我正在制作定制的嵌套Blazor组件,但我似乎没有让它以我想要的方式工作。
目标是拥有一个具有"ContentHeader“和"ContentBody”属性的"Content“组件。但是,"ContentHeader“应该是另一个具有"Title”和"ActionBar“属性的自定义组件。所需的用法如下:
<Content>
<ContentHeader>
<Title>
Title
</Title>
<ActionBar>
<button>Test button</button>
</ActionBar>
</ContentHeader>
<ContentBody>
Body
</ContentBody>
</Content>Content组件:
<CascadingValue Value="this">
<div class="content-container">
@ContentHeader(Header)
<div class="content-body">
@ContentBody
</div>
</div>
</CascadingValue>
@code {
[Parameter]
public RenderFragment<ContentHeader> ContentHeader { get; set; }
[Parameter]
public RenderFragment ContentBody { get; set; }
public ContentHeader Header { get; set; }
public async Task SetContentHeader(ContentHeader contentHeader)
{
Header = contentHeader;
await InvokeAsync(StateHasChanged);
}
}"ContentHeader“组件:
<div class="content-header">
<h3>@Title</h3>
<div class="content-header-action-bar">
@ActionBar
</div>
</div>
@code {
[CascadingParameter]
public Content Content { get; set; }
[Parameter]
public RenderFragment Title { get; set; }
[Parameter]
public RenderFragment ActionBar { get; set; }
protected override async Task OnInitializedAsync()
{
await Content.SetContentHeader(this);
await base.OnInitializedAsync();
}
}我得到的实际渲染输出是这样的:
<div class="content-container">
<!--!-->
Title
<!--!-->
<!--!-->
<button>Test button</button>
<!--!-->
<div class="content-body">
<!--!-->
Body
</div>
</div>似乎"ContentHeader“组件的标记被完全忽略了。缺少"HeaderComponent“标题周围的<h3></h3>标记,并且该按钮未放置在<div class="content-header-action-bar"></div>中
我还注意到"ContentHeader“的OnInitializedAsync没有被触发。
我做错了什么?我用的是正确的方法吗?
在此之前,非常感谢您。
亲切的问候
发布于 2020-07-27 05:37:16
你尝试这样做的方式是不正确的,除非你正在呈现你自己的@ActionBar,而我认为你并没有试图这样做。
这来自我的开源项目Blazor Chat:
来源:https://github.com/DataJuggler/BlazorChat
Live Site:没有多少用户同时访问https://blazorchat.com
这是我的索引页面。ScreenType是一个枚举变量。
@if (ScreenType == ScreenTypeEnum.Join)
{
<Join Parent=this></Join>
}
else if (ScreenType == ScreenTypeEnum.Login)
{
<Login Parent=this></Login>
}
else
{
<Chat Parent=this></Chat>
@if (TextHelper.Exists(Message))
{
<div class="message">
@Message
</div>
}
} 使用Parent=this,子组件和父组件以及页面可以通过接口进行通信。我不打算在这里深入探讨这个问题,但如果有人对此感到好奇,这里有一篇我在大约六个月前写的关于这个主题的博客文章:
https://datajugglerblazor.blogspot.com/2020/01/how-to-use-interfaces-to-communicate.html
我不能发布整个项目,但这里有一些相关的部分,可能会帮助你更好地理解父/子组件。
这是一个具有多个子组件的组件的项目示例:
Chat.razor:
@if (HasUser)
{
@if (Connected)
{
<div class="chatroom2">
@if (ListHelper.HasOneOrMoreItems(Messages))
{
foreach (SubscriberMessage message in Messages)
{
<SpeechBubble Message=message>
</SpeechBubble>
}
}
</div>
<div class="whoseonlist">
@if (ListHelper.HasOneOrMoreItems(Names))
{
@foreach (SubscriberCallback callback in Names)
{
<button class="listbutton" @onclick="(Action<EventArgs>) (args =>
SendPrivateMessageClicked(args, callback.Id))">@callback.Name</button><br />
}
}
<textarea class="typedtext" @bind="MessageText"></textarea>
<button class="greenbutton8"
@onclick="BroadCastMessage">Broadcast</button>
<div class="privatemessageinfo">
Click a name to send<br />a private message.
</div>
</div>
}
else
{
<div id="ChatRoom" class="chatroom">
<div class="moveup4">
Enter Chat<br />
<input type="text" @bind="SubscriberName" /><br />
<button class="greenbutton6"
@onclick="@RegisterWithServer">Connect</button>
</div>
</div>
}
}
else
{
<div class="loginorjointochat">
</div>
}如果您确实希望呈现HTML,则发言气泡具有一个message属性,它将清理HTML。因此,如果用户输入,我发现了这个很酷的站点https://pixeldatabase.net (我的站点),过滤后的代码将呈现为超链接(我做了文本替换并将其转换为锚点标记),但如果消息包含粗体标记,文本将呈现为粗体,或者HTML换行符用于分行,等等。
foreach (SubscriberMessage message in Messages)
{
<SpeechBubble Message=message>
</SpeechBubble>
}这要归功于Nuget包: HtmlSanitizer
它的参考资料是Ganss.XSS,我花了一段时间才弄明白。
下面是一个带有扩展方法的类,如果有人需要的话:
using Ganss.XSS;
using Microsoft.AspNetCore.Components;
namespace BlazorChat
{
public static class MarkupStringExtensions
{
public static MarkupString Sanitize(this MarkupString markupString)
{
return new MarkupString(SanitizeInput(markupString.Value));
}
private static string SanitizeInput(string value)
{
var sanitizer = new HtmlSanitizer();
return sanitizer.Sanitize(value);
}
}
}以下是呈现的HTML文本的屏幕截图:

https://stackoverflow.com/questions/63103591
复制相似问题