当 url 查询更改时强制 Blazor 组件重新渲染

Jas*_*yer 5 c# blazor blazor-server-side

我读过的所有内容都指向我使用 NavigationManager.LocationChanged 事件,但是它不会检测仅查询字符串何时更改。因此,没有任何东西着火。

我已经尝试过这里建议的内容,但这并不符合我的要求。

每次当前路由中的查询参数发生变化时,我都需要我的组件重新渲染。有人能够做到这一点吗?

更新:

这是我的代码示例:

@page "/accounts"

@if (Accounts != null)
{
    <table>
        <tbody>
            @foreach (var account in Accounts)
            {
                <tr>
                    <td>
                        <NavLink href="/accounts/?accountId={account.AccountId}">@Account.Name</NavLink>
                    </td>
                </tr>
            }
        </tbody>
    </table>
}

@if (Account != null)
{
    <div>
        <h2>@Account.Name</h2>
    </div>
}

@implements IDisposable
@inject NavigationManger NavManager
@inject AccountService AccountService

@code {
    protected Guid Id { get; set; } = Guid.NewGid();
    protected Guid AccountId { get; set; } = Guid.Empty;
    protected List<AccountModel> Accounts { get; set; }
    protected AccountModel Account { get; set; }

    protected override void OnInitialized()
    {
        NavManager.LocationChanged += LocationChanged;
    }

    protected async override Task OnParametersSetAsync()
    {
        if (AccountId != Guid.Empty)
        {
            Account = await AccountService.GetAsync(AccountId);
        }
        else
        {
            Accounts = await AccountService.GetAllAsync();
        }
    
        StateHasChanged();
    }

    void LocationChanged(object sender, LocationChangedEventArgs e)
    {
        Id = Guid.NewGuid();
    
        StateHasChanged();
    }
    
    void IDisposable.Dispose()
    {
        NavManager.LocationChanged -= LocationChanged;
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是LocationChanged(object, LocationChangedEventArgs)当仅查询参数更改时不会触发。这是有道理的,路线是一样的/accounts

基本上我有一个页面来显示帐户列表并查看单个帐户。/accounts我希望查看列表时的路线和“/accounts?accountId=someAccountId”作为我查看列表时的路线。使用标准 NavLink 组件不会触发组件的重新渲染,LocationChanged 事件也不会。即使设置新的 Id 值也不行。了解如何StateHasChanged仅在值发生更改时重新呈现组件。

Jas*_*yer 5

我最终得到了我想要的工作,如下所示:

@page "/accounts"

@if (Accounts != null)
{
    <table>
        <tbody>
            @foreach (var account in Accounts)
            {
                <tr>
                    <td>
                        <NavLink href="/accounts/?accountId={account.AccountId}">@Account.Name</NavLink>
                    </td>
                </tr>
            }
        </tbody>
    </table>
}

@if (Account != null)
{
    <div>
        <h2>@Account.Name</h2>
    </div>
}

@implements IDisposable
@inject NavigationManger NavManager
@inject AccountService AccountService

@code {
    protected Guid Id { get; set; } = Guid.NewGid();
    protected Guid AccountId { get; set; } = Guid.Empty;
    protected List<AccountModel> Accounts { get; set; }
    protected AccountModel Account { get; set; }

    protected override void OnInitialized()
    {
        NavManager.LocationChanged += LocationChanged;
    }

    protected async override Task OnParametersSetAsync()
    {
        if (AccountId != Guid.Empty)
        {
            Account = await AccountService.GetAsync(AccountId);
        }
        else
        {
            Accounts = await AccountService.GetAllAsync();
        }
    
        StateHasChanged();
    }

    async void LocationChanged(object sender, LocationChangedEventArgs e)
    {
        if (AccountId != Guid.Empty)
        {
            Account = await AccountService.GetAsync(AccountId);
        }
        else
        {
            Accounts = await AccountService.GetAllAsync();
        }
    
        StateHasChanged();
    }
    
    void IDisposable.Dispose()
    {
        NavManager.LocationChanged -= LocationChanged;
    }
}
Run Code Online (Sandbox Code Playgroud)

我最终只是调用了我想要在第一次渲染上手动运行的所有相同代码。我希望(错误地假设)我可以告诉它通过更改一个本地属性然后调用StateHasChanged.

现在,当我在组件之间切换时,"/accounts"组件"/accounts?accountId=someId"会根据需要重新渲染。