首页 > 解决方案 > 未触发事件且 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)。

标签: asp.net-coreeventsblazorblazor-client-side

解决方案


我终于设法解决了我的问题。我无法使用我的服务,因为它没有注册为 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();
    }
}

必须有更好的解决方案。


推荐阅读