【发布时间】:2020-03-01 13:37:49
【问题描述】:
我已阅读文章“3 Ways to Communicate Between Components in Blazor”并尝试这样做。 我在@body 下有消息组件,并且必须根据@body 组件中的用户操作更改消息
@inject ClientMessage clientMessage
@inherits LayoutComponentBase
@using Site.Shared.Components
<div class="sidebar">
<AdminMenu />
</div>
<div class="main">
<div class="content px-4">
@Body
</div>
<Message/>
</div>
@code
{
protected async Task ChangeState()
{
await InvokeAsync(StateHasChanged);
}
protected override void OnInitialized()
{
clientMessage.MsgChange += ChangeState;
}
}
消息组件:
@inject ClientMessage clientMessage
<div style="@(IsVisble ? "display:block" : "display:none")" class="@MsgClass" role="alert">
@if (clientMessage != null)
{
@clientMessage.Message
}
</div>
@code {
public bool IsVisble
{
get
{
if (string.IsNullOrEmpty(@clientMessage.Message))
{
return false;
}
return true;
}
}
public string MsgClass
{
get
{
if (clientMessage == null)
{
return string.Empty;
}
string msgClass;
switch (clientMessage.MsgType)
{
case EMsgType.Info:
msgClass = "alert alert-info";
break;
case EMsgType.Success:
msgClass = "alert alert-success";
break;
case EMsgType.Warning:
msgClass = "alert alert-warning";
break;
case EMsgType.Error:
msgClass = "alert alert-danger";
break;
case EMsgType.NoMsg:
default:
msgClass = string.Empty;
break;
}
return msgClass;
}
}
}
消息类
public class ClientMessage
{
public event Func<Task> MsgChange;
public ClientMessage(string msg, EMsgType msgType)
{
this.Message = msg;
this.MsgType = msgType;
NotifyStateChanged();
}
public void SetMsg(string msg, EMsgType msgType)
{
this.Message = msg;
this.MsgType = msgType;
NotifyStateChanged();
}
public string Message { get; set; }
public EMsgType MsgType { get; set; }
private void NotifyStateChanged()
{
if (MsgChange != null)
{
MsgChange.Invoke();
}
}
}
ClientMessage 类由 DI 作为单例注入。如果我在 @body 组件中调用 SetMsg(newMsgm, msgType) 则调用 ChangeState() 方法但没有发生任何事情,我的意思是组件没有重新渲染。如果我改为“InvokeAsync”使用“Invoke”,则会出现错误“当前线程未与 Dispatcher 关联。在触发渲染或组件状态时,使用 InvokeAsync() 将执行切换到 Dispatcher。”。如果我重新加载页面,我可以看到消息。
我做错了什么以及如何强制重新渲染消息组件?
【问题讨论】:
-
您的消息组件没有参数,因此 Blazor 将假定它是静态的。如果您将 MainLayout 的
code部分移动到 Message 组件,那么只要消息发生更改,它就会重新呈现自己。您还应该实现 IDisposable - 这样您就可以取消订阅 MsgChange 事件 - 以确保完整性。
标签: c# asp.net-core .net-core blazor