Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/BootstrapBlazor/Components/Layout/Layout.razor
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@
RefreshToolbarTooltipText="@RefreshToolbarTooltipText" FullscreenToolbarTooltipText="@FullscreenToolbarTooltipText"
OnToolbarRefreshCallback="OnToolbarRefreshCallback" TabHeader="TabHeader"
Body="@Main" NotAuthorized="NotAuthorized!" NotFound="NotFound!" NotFoundTabText="@NotFoundTabText"
EnableErrorLogger="EnableErrorLogger" ShowErrorLoggerToast="ShowErrorLoggerToast"
EnableErrorLogger="@_enableErrorLogger" ShowErrorLoggerToast="@_showToast"
ErrorLoggerToastTitle="@ErrorLoggerToastTitle">
</Tab>;

Expand Down
37 changes: 34 additions & 3 deletions src/BootstrapBlazor/Components/Tab/TabItemContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace BootstrapBlazor.Components;

class TabItemContent : IComponent
class TabItemContent : IComponent, IHandlerException, IDisposable
{
/// <summary>
/// Gets or sets the component content. Default is null
Expand All @@ -18,6 +18,15 @@ class TabItemContent : IComponent
[CascadingParameter, NotNull]
private Tab? TabSet { get; set; }

[Inject, NotNull]
private DialogService? DialogService { get; set; }

[Inject]
[NotNull]
private IOptionsMonitor<BootstrapBlazorOptions>? Options { get; set; }

private ErrorLogger? _logger;

private RenderHandle _renderHandle;

void IComponent.Attach(RenderHandle renderHandle)
Expand Down Expand Up @@ -55,11 +64,17 @@ private RenderFragment RenderItemContent(RenderFragment? content) => builder =>
builder.OpenComponent<ErrorLogger>(0);
builder.AddAttribute(1, nameof(ErrorLogger.ChildContent), content);

var enableErrorLogger = TabSet.EnableErrorLogger;
var showToast = TabSet.ShowErrorLoggerToast;
var enableErrorLogger = TabSet.EnableErrorLogger ?? Options.CurrentValue.EnableErrorLogger;
var showToast = TabSet.ShowErrorLoggerToast ?? Options.CurrentValue.ShowErrorLoggerToast;
builder.AddAttribute(2, nameof(ErrorLogger.EnableErrorLogger), enableErrorLogger);
builder.AddAttribute(3, nameof(ErrorLogger.ShowToast), showToast);
builder.AddAttribute(4, nameof(ErrorLogger.ToastTitle), TabSet.ErrorLoggerToastTitle);
builder.AddAttribute(5, nameof(ErrorLogger.OnInitializedCallback), new Func<ErrorLogger, Task>(logger =>
{
_logger = logger;
_logger.Register(this);
return Task.CompletedTask;
}));
builder.CloseComponent();
};

Expand All @@ -75,4 +90,20 @@ public void Render()
_key = new object();
RenderContent();
}

/// <summary>
/// HandlerException 错误处理方法
/// </summary>
/// <param name="ex"></param>
/// <param name="errorContent"></param>
public Task HandlerException(Exception ex, RenderFragment<Exception> errorContent) => DialogService.ShowErrorHandlerDialog(errorContent(ex));

/// <summary>
/// IDispose 方法用于释放资源
/// </summary>
public void Dispose()
{
_logger?.UnRegister(this);
GC.SuppressFinalize(this);
}
}
42 changes: 42 additions & 0 deletions test/UnitTest/Components/ErrorLoggerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,46 @@ public void ErrorContent_Ok()
cut.InvokeAsync(() => button.Click());
cut.Contains("Attempted to divide by zero.error_content_template");
}

[Fact]
public async Task TabItem_Error()
{
var cut = Context.RenderComponent<BootstrapBlazorRoot>(pb =>
{
pb.AddChildContent<Tab>(pb =>
{
pb.AddChildContent<TabItem>(pb =>
{
pb.Add(a => a.Text, "Text1");
pb.Add(a => a.ChildContent, builder => builder.AddContent(0, RenderButton()));
});
});
});

var button = cut.Find("button");
await cut.InvokeAsync(() => button.Click());

// 页面不崩溃,由弹窗显示异常信息
cut.Contains("<div class=\"error-stack\">TimeStamp:");

// 单元测试覆盖 TabItemContent Dispose 方法
var handler = Activator.CreateInstance("BootstrapBlazor", "BootstrapBlazor.Components.TabItemContent");
Assert.NotNull(handler);
var content = handler.Unwrap();
Assert.NotNull(content);

Assert.IsType<IDisposable>(content, exactMatch: false);
((IDisposable)content).Dispose();
}

private RenderFragment RenderButton() => builder =>
{
builder.OpenComponent<Button>(0);
builder.AddAttribute(2, nameof(Button.OnClick), EventCallback.Factory.Create<MouseEventArgs>(this, e =>
{
var a = 0;
_ = 1 / a;
}));
builder.CloseComponent();
};
}
1 change: 1 addition & 0 deletions test/UnitTest/Components/ImageTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ public void IsIntersectionObserver_Ok()
{
var cut = Context.RenderComponent<ImageViewer>(pb =>
{
pb.Add(a => a.ZoomSpeed, 0.5d);
pb.Add(a => a.Url, "https://www.blazor.zone/images/logo.png");
pb.Add(a => a.IsIntersectionObserver, true);
});
Expand Down