从零开始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.SubscribeNotify注册到我们的消息系统中。


同时我们在页面销毁的时候需要注销我们的订阅,所以我们的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

posted @ 2022-08-23 11:22  jvx  阅读(1842)  评论(0编辑  收藏  举报