mirror of
https://github.com/radzenhq/radzen-blazor.git
synced 2026-07-08 18:16:08 +00:00
RadzenTabs: ensure render state is restored when tab event handlers throw
Follow-up to the #2558 fix. In SelectTab the StateHasChanged call was skipped
if Change/SelectedIndexChanged threw, leaving the component stale (multiple
tabs visually active); in SelectTabOnClient a throw left shouldRender stuck at
false, blocking all further renders. Wrap both in finally so the render state
is always restored. Addresses review feedback on commit df1dfa713.
Fixes #2558
This commit is contained in:
@@ -230,6 +230,27 @@ namespace Radzen.Blazor.Tests
|
||||
Assert.True(component.RenderCount > renderCountBefore);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Tabs_ChangeHandlerThrows_StillRendersSelectedTab()
|
||||
{
|
||||
using var ctx = new TestContext();
|
||||
|
||||
var component = ctx.RenderComponent<RadzenTabs>(parameters => parameters
|
||||
.Add(p => p.SelectedIndex, 0)
|
||||
.Add(p => p.Change, (int _) => throw new System.InvalidOperationException("boom"))
|
||||
.Add(p => p.Tabs, TabsFragmentWithContent(("First", "First-Content"), ("Second", "Second-Content")))
|
||||
);
|
||||
|
||||
Assert.Contains("First-Content", component.Markup);
|
||||
|
||||
var secondTab = component.FindAll("button[role='tab']")[1];
|
||||
var ex = Record.Exception(() => secondTab.Click());
|
||||
|
||||
Assert.NotNull(ex);
|
||||
Assert.Contains("Second-Content", component.Markup);
|
||||
Assert.DoesNotContain("First-Content", component.Markup);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Tabs_NonNavigationKeyDown_DoesNotBlockSubsequentRenders()
|
||||
{
|
||||
|
||||
@@ -210,22 +210,27 @@ namespace Radzen.Blazor
|
||||
|
||||
SetFocusedIndex();
|
||||
|
||||
if (raiseChange)
|
||||
try
|
||||
{
|
||||
await Change.InvokeAsync(selectedIndex);
|
||||
|
||||
await SelectedIndexChanged.InvokeAsync(selectedIndex);
|
||||
|
||||
try
|
||||
{
|
||||
await Element.FocusAsync(preventScroll: true);
|
||||
}
|
||||
catch (JSDisconnectedException)
|
||||
if (raiseChange)
|
||||
{
|
||||
await Change.InvokeAsync(selectedIndex);
|
||||
|
||||
await SelectedIndexChanged.InvokeAsync(selectedIndex);
|
||||
|
||||
try
|
||||
{
|
||||
await Element.FocusAsync(preventScroll: true);
|
||||
}
|
||||
catch (JSDisconnectedException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
finally
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -342,9 +347,15 @@ namespace Radzen.Blazor
|
||||
}
|
||||
|
||||
shouldRender = false;
|
||||
await Change.InvokeAsync(selectedIndex);
|
||||
await SelectedIndexChanged.InvokeAsync(selectedIndex);
|
||||
shouldRender = true;
|
||||
try
|
||||
{
|
||||
await Change.InvokeAsync(selectedIndex);
|
||||
await SelectedIndexChanged.InvokeAsync(selectedIndex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
shouldRender = true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user