【问题标题】:Event is not triggered and Blazor component won't refresh未触发事件且 Blazor 组件不会刷新
【发布时间】:2020-01-06 05:39:57
【问题描述】:

我想根据授权更改使我的组件刷新。这是我的组件:

@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)。

【问题讨论】:

  • 1.我认为您需要将AuthService.RefreshRequested += StateHasChanged; 放在Identity = $"...."; 2 之后。此外,您必须确保您的组件就在那里并且当有人调用Token(...) 方法时 NOT 被处理
  • @itminus 这是共享组件。在调用Token(...) 时不会释放它

标签: asp.net-core events blazor blazor-client-side


【解决方案1】:

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

一定有更好的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-31
    • 2020-05-16
    • 2023-03-26
    • 2020-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多