从零开始Blazor Server(13)--消息通知
我们现在做了用户管理、角色管理、菜单管理。
但是大家有没有发现,我们的菜单要变化的话必须要刷新页面才行。这个体验感觉不太好。
今天我们就用全局通知组件来解决这个问题。
首先我们要改造以下我们的MainLayout
,之前我们是在OnInitialized
中直接获取的菜单,这样肯定没法刷新了,所以我们要先把获取菜单的内容单独拿出来
private void RefreshMenu()
{
_user = UserEntity.Where(x => x.UserName == Furion.App.User.FindFirstValue(ClaimTypes.Name)).First();
if (_user == null)
{
return;
}
_menuItems = CreateMenuItems(MenuEntity.Where(x => x.Roles!.Any(y => y.Id == _user.RoleId)).ToList(), 0);
}
这样我们就需要在OnInitialized
调用以下我们的RefreshMenu
。
protected override void OnInitialized()
{
base.OnInitialized();
RefreshMenu();
}
然后我们就可以注册全局的监听了。
在MainLayout
中添加
@inject IDispatchService<string> DispatchService
将IDispatchService
注入进来,这里我们只需要返回一个是什么就行了,所以泛型就只用了string
,如果你需要接收更复杂的内容,可以修改这里的泛型类。
然后我们需要添加一个接收请求的方法
private Task Notify(DispatchEntry<string> arg)
{
if (arg.Entry == "role")
{
RefreshMenu();
InvokeAsync(StateHasChanged);
}
return Task.CompletedTask;
}
这里我们只对角色页面进行处理。其他页面暂不处理,因为原理都是一样的,那些代码就不写了。所以我们只判断以下,如果发送的内容是role
,那么我们就执行刷新菜单的操作。
然后我们需要注册这个Notify
,还是在我们的OnInitialized
中,终极版本如下
protected override void OnInitialized()
{
base.OnInitialized();
RefreshMenu();
DispatchService.Subscribe(Notify);
}
我们使用DispatchService.Subscribe
把Notify
注册到我们的消息系统中。
同时我们在页面销毁的时候需要注销我们的订阅,所以我们的MainLayout
需要实现IDisposable
接口。
@implements IDisposable
然后在Dispose
方法中编写注销事件
public void Dispose()
{
DispatchService.UnSubscribe(Notify);
}
然后我们来处理Role
页面,这个页面里也是要先注入
@inject IDispatchService<string> DispatchService
然后我们在SavePermission
方法最后,通知一下即可。
DispatchService.Dispatch(new DispatchEntry<string>(){Entry = "role"});
这里我们说一下自己是role
,才可以和MainLayout
判断对应。
整个SavePermission
private void SavePermission()
{
if (RoleEntity == null)
{
return;
}
var menus = new List<MenuEntity>();
SaveRole(Menus!.Where(x => x.CheckedState != CheckboxState.UnChecked), menus);
RoleEntity.Permissions = menus;
RoleEntity.SaveMany(nameof(RoleEntity.Permissions));
RoleModal?.Toggle();
DispatchService.Dispatch(new DispatchEntry<string>(){Entry = "role"});
}
代码在代码在https://github.com/j4587698/BlazorLearn,分支lesson13