提问人:beginner 提问时间:5/4/2023 最后编辑:beginner 更新时间:5/9/2023 访问量:207
多个窗口中的 Web 事件处理 (Blazor)
Web event handling in multiple windows (Blazor)
问:
我刚刚开始上网,这次我在事件处理方面遇到了麻烦。我使用 blazor 进行开发,但这似乎是一个普遍适用的问题。
我被困的地方是这个。我想在收到消息时通知页面。当我有一个浏览器屏幕时,我没有遇到任何问题,但是当我在打开两个屏幕的情况下测试我的网络时,事件无法正常工作。如何解决此问题?
下面是我的代码。
ServiceInfoReceiveHandler.cs
public event EventHandler<(string contentType, string serverName, string message)> InstallServiceInfoReceived;
...
public void Receive(BasicDeliverEventArgs eventArgs)
{
if (contentType == "SVCMGMT/INSTALL/SVCINFO")
{
InstallServiceInfoReceived?.Invoke(this, (contentType, serverName, message));
...
}
}
我像这样触发事件,每当有消息传入时,总是调用接收函数。这不是消息没有到达的问题。
page.razor
@inject ServiceInfoReceiveHandler _serviceInfoReceiveHandler
protected override async Task OnInitializedAsync()
{
_serviceInfoReceiveHandler.InstallServiceInfoReceived += OnServiceInfoReceived;
}
private async void OnServiceInfoReceived(object sender, (string contentType, string serverName, string message) e)
{
...
}
我想要结果的剃刀页面如上所示,但未调用 OnInfoReceived。
答:
1赞
MrC aka Shaun Curtis
5/4/2023
#1
下面是用于在页面与事件之间进行通信的 Blazor 通知模式的简单演示。
首先是通知服务。
namespace SO76170542.Data;
public class HelloService
{
public event EventHandler<HelloEventArgs>? HelloChanged;
private string? _hello;
public string HelloMessage => _hello ?? "No Message Set";
public void NotifyHelloChanged(string? hello)
{
_hello = hello;
this.HelloChanged?.Invoke(this, new(hello));
}
}
public class HelloEventArgs : EventArgs
{
public string? Hello { get; set; }
public HelloEventArgs(string? hello)
=> Hello = hello;
}
已注册 程序。
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
builder.Services.AddSingleton<HelloService>();
var app = builder.Build();
以及用于生成和使用消息的页面。
@page "/"
@inject HelloService helloService
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<div class="m-2">
<button class="btn btn-dark" @onclick=this.UpdateHello>Update Hello</button>
</div>
<div class="alert alert-primary">@helloService.HelloMessage</div>
@code {
// Register the event handler
protected override void OnInitialized()
=> this.helloService.HelloChanged += this.OnHelloChanged;
private Task UpdateHello()
{
helloService.NotifyHelloChanged($"Hello Blazor at {DateTime.Now.ToLongTimeString()}");
return Task.CompletedTask;
}
public void OnHelloChanged(object? sender, HelloEventArgs e)
=> InvokeAsync(this.StateHasChanged);
// We must de-register the even handler
public void Dispose()
=> this.helloService.HelloChanged -= this.OnHelloChanged;
}
您可以在此处看到相同的模式:如何触发/刷新我的主 .RAZOR 页面,该主 .API 调用完成时的 RAZOR 页面?FetchData
评论
0赞
beginner
5/5/2023
感谢您的友好回复。我还没有在我现有的代码上尝试过,但根据您的示例,您似乎将 HelloService 设置为单例,这与我的不同。我将其设置为作用域,但是否必须将其设置为单例?
0赞
MrC aka Shaun Curtis
5/5/2023
如果将其设置为作用域,则实例将仅存在于 Hub SPA 会话的作用域内。在我上面的图片中,您将有 4 个实例,每个会话一个,我认为这是您正在观察到的,但不想要,
0赞
beginner
5/8/2023
我仍然需要测试更多,但更改为单例似乎已经解决了这个问题。但是,即使我将您发布的示例更改为 scoped,按下按钮的窗口中的值也会发生变化,这是我想要的结果。有没有可能我遇到麻烦的原因是因为我没有直接通过按钮调用事件,而是在加载页面时通过消息代理调用事件,当响应到来时,它会在触发事件的过程中流向另一个对象(另一个窗口)?
0赞
MrC aka Shaun Curtis
5/8/2023
你只想在一个屏幕中接收讯息吗?消息从何而来?
0赞
beginner
5/9/2023
我的消息是通过客户端的 RabbitMQ 传递的。我不一定需要在一个屏幕上接收它,我认为像你那样将它实现为单例会起作用,但我不熟悉单例,所以我只是想知道是否存在我不知道的问题。所以我想知道为什么在您的示例中,当它被限定时,当我按下按钮时,我在该屏幕上获得该事件,但在上面的旧代码中,我在随机屏幕上获得它。
评论