asp.net-core - 未触发事件且 Blazor 组件不会刷新
问题描述
我想根据授权更改刷新我的组件。这是我的组件:
@inject IAuthService AuthService
@implements IDisposable
<AuthorizeView>
<Authorized>
Logged as: @Identity
</Authorized>
<NotAuthorized>
</NotAuthorized>
</AuthorizeView>
@code
{
private string Identity { get; set; }
protected override async Task OnInitializedAsync()
{
AuthService.RefreshRequested += StateHasChanged;
Identity = $"{(await AuthService.GetClaimFromToken("sub"))?.Value} ({(await AuthService.GetClaimFromToken("unique_name"))?.Value})";
}
public void Dispose()
{
AuthService.RefreshRequested -= StateHasChanged;
}
}
这是我服务的一部分:
public class AuthService: IAuthService
{
// ...
public event Action RefreshRequested;
public async Task<RequestResponse> Token(LoginModel loginModel)
{
// some logic
CallRequestRefresh();
return JsonConvert.DeserializeObject<RequestResponse>(result);
}
private void CallRequestRefresh()
{
RefreshRequested?.Invoke();
}
}
Token(...)
方法用于其他组件。我不知道为什么在提到的组件中,StateHasChanged
没有被触发。
我真正想要实现的只是提供一些更新Identity
属性的方法,使用给定的异步方法(GetClaimFromToken
)。
解决方案
我终于设法解决了我的问题。我无法使用我的服务,因为它没有注册为 Singleton。我创建了一个类AppState
并将其注册为 Singleton:
public class AppState
{
public event Action RefreshRequested;
public void TriggerRefreshAction()
{
StateChanged();
}
private void StateChanged()
{
RefreshRequested?.Invoke();
Console.WriteLine("State has changed");
}
}
并将其注入组件和AuthService
. 我还需要将组件的一些逻辑更改为StateHasChanged()
触发器OnAfterRender/OnAfterRenderAsync
,这会更新我的字符串Identity
但不会更改 UI。现在似乎可以工作,但我不喜欢在 UI 上更新值的方法:
@inject IAuthService AuthService
@inject AppState AppState
@implements IDisposable
<AuthorizeView>
<Authorized>
Logged as: @Identity
</Authorized>
<NotAuthorized>
</NotAuthorized>
</AuthorizeView>
@code
{
private string Identity { get; set; }
private bool Refresh { get; set; }
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
await UpdateIdentity();
AppState.RefreshRequested += RefreshComponent;
}
public void Dispose()
=> AppState.RefreshRequested -= RefreshComponent;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (Refresh)
{
await UpdateIdentity();
Refresh = false;
StateHasChanged();
}
await base.OnAfterRenderAsync(firstRender);
}
private async Task UpdateIdentity()
=> Identity = $"{(await AuthService.GetClaimFromToken("sub"))?.Value} ({(await AuthService.GetClaimFromToken("unique_name"))?.Value})";
private void RefreshComponent()
{
Refresh = true;
StateHasChanged();
}
}
必须有更好的解决方案。
推荐阅读
- c++ - 有没有办法通过安装脚本或批处理检查文件的编码?
- java - 如何在java中解析JSON模式的所有引用
- c - 定时器在正常模式下触发 AVR128DB48 上的中断
- mysql - 谁能解释为什么 @Declare 和 @Set 在声明和设置工作正常时抛出错误?
- node.js - 如何让用户在一个频道中只谈一次?
- c# - Unity C#脚本变量在脚本中更改时不会在游戏中更改
- c++ - 在 socketpair() 上添加协议层以获得 SSL-WebSocket (boost::beast?)
- ruby - 在哪里可以找到像 instance_exec 这样的 Native Ruby 源代码?
- tensorflow - plt.show() 不显示图像
- python - “ init_fs_encoding: 未能获取文件系统编码的 Python 编解码器 Python 运行时状态:核心已初始化”