通知所有已添加学生的客户并更新用户界面 [英] Notify all clients of added student and update ui
问题描述
我有一个出色的Web组装项目和一个Signal r服务项目,我想在添加一个学生时调用对ui所做的更改. 目前,我必须刷新页面才能看到添加的内容.
I have a blazor web assembly project and a signal r service project I would like to invoke the changes to the ui when I add a student. Currently I have to refesh the page to see the addition.
StudentService.cs
StudentService.cs
public class StudentService
{
public HubConnection connection;
public StudentServicen()
{
connection = new HubConnectionBuilder()
.WithUrl(".../StudentsHub")
.Build();
connection.StartAsync();
}
public async Task<List<Students>> GetAllStudents() =>
await connection.InvokeAsync<List<Students>>("GetAllStudents"));
public async Task<Boolean> AddStudent(StudentData student) =>
await connection.InvokeAsync<Boolean>("AddStudent", student);
}
Students.razor
Students.razor
@inject StudentService StudentService
<ul >
@foreach (var student in students)
{
<li>@student.Name</li>
}
</ul>
@code {
private List<Students> students = new List<Students>();
protected override async Task OnInitializedAsync()
{
students = await StudentService.GetAllStudents();
}
另一个项目中的学生中心.
Students hub in another project.
public class StudentsHub : Hub
{
public Task<List<Students>> GetAllStudents() =>
Task.FromResult(getAllStudents.GetAll());
public Boolean AddStudent(StudentData student) =>
studentService.AddStudent(student);
}
推荐答案
您已经提供了部分代码段,因此我创建了一个有效的小样本,并使用自定义服务访问服务器中心,并将值返回给将定制服务注入其中的剃刀组件.
You've provided partial code snippets, so I created a small sample which is working, and using a custom service to access the server hub, and return values to a razor component into which the custom service is injected.
请注意,在使用服务和回调时,必须使用InvokeAsync方法,该方法将分派给Blazor的SynchronizationContext,这是一个强制执行单个逻辑线程的对象.
Note that when you use services and call backs you must use the InvokeAsync method, which dispatches to Blazor's SynchronizationContext, an object that enforces a single logical thread of execution.
这是完整的代码,对其进行复制和测试,看看它是否可以帮助您使用应用程序...
Here's the complete code, copy and test it, and see if it can help you with your app...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.SignalR.Client;
namespace BlazorSignalRApp.Client
{
public class UserService
{
public event Action Notify;
public string User { get; set; }
public string Message { get; set; }
HubConnection hubConnection;
public UserService(NavigationManager navigationManager)
{
hubConnection = new HubConnectionBuilder()
.WithUrl(navigationManager.ToAbsoluteUri("/chatHub"))
.Build();
hubConnection.On<string, string>("ReceiveMessage", (user,
message) =>
{
User = user;
Message = message;
if (Notify != null)
{
Notify?.Invoke();
}
});
hubConnection.StartAsync();
hubConnection.SendAsync("SendMessage", null, null);
}
public void Send(string userInput, string messageInput) =>
hubConnection.SendAsync("SendMessage", userInput, messageInput);
public bool IsConnected => hubConnection.State ==
HubConnectionState.Connected;
}
}
Index.razor
@page "/"
@inject UserService UserService
@implements IDisposable
<div>
<label for="userInput">User:</label>
<input id="userInput" @bind="@userInput" />
</div>
<div class="form-group">
<label for="messageInput">Message:</label>
<input id="messageInput" @bind="@messageInput" />
</div>
<button @onclick="@(() => UserService.Send(userInput, messageInput))"
disabled="@(!UserService.IsConnected)">Send Message</button>
<hr />
<ul id="messagesList">
@foreach (var message in messages)
{
<li>@message</li>
}
</ul>
@code {
List<string> messages = new List<string>();
string userInput;
string messageInput;
protected override void OnInitialized()
{
UserService.Notify += OnNotify;
}
public void OnNotify()
{
if (!string.IsNullOrEmpty(UserService.User))
{
var encodedMsg = UserService.User + " says " +
UserService.Message;
messages.Add(encodedMsg);
}
InvokeAsync(() =>
{
StateHasChanged();
});
}
public void Dispose()
{
UserService.Notify -= OnNotify;
}
}
ChatHub.cs(将此文件放置在Server项目的Hubs文件夹中)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
namespace BlazorSignalRApp.Server.Hubs
{
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
}
Program.cs(客户端项目)
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Text;
using Microsoft.AspNetCore.Blazor.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Components;
namespace BlazorSignalRApp.Client
{
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddSingleton<UserService>();
builder.RootComponents.Add<App>("app");
await builder.Build().RunAsync();
}
}
}
希望这对您有帮助...
Hope this helps...
这篇关于通知所有已添加学生的客户并更新用户界面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!