From 0d4de394b65d4ef7ee315d6a806c7d6ceb83fd26 Mon Sep 17 00:00:00 2001 From: capdiem Date: Wed, 4 Sep 2024 09:25:14 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20(Service):=20breakpoint=20servic?= =?UTF-8?q?e=20doesn't=20work=20when=20interactive=20per=20page/component?= =?UTF-8?q?=20enabled=20(#2131)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Masa.Blazor/Components/App/MApp.razor.cs | 16 --------- src/Masa.Blazor/Core/MasaComponentBase.cs | 11 ++++++ .../Services/Breakpoint/Breakpoint.cs | 34 +++++++++++-------- src/Masa.Blazor/Utils/Throttle.cs | 24 +++++++++++++ 4 files changed, 55 insertions(+), 30 deletions(-) create mode 100644 src/Masa.Blazor/Utils/Throttle.cs diff --git a/src/Masa.Blazor/Components/App/MApp.razor.cs b/src/Masa.Blazor/Components/App/MApp.razor.cs index 2ec5054e1c..b04bd40477 100644 --- a/src/Masa.Blazor/Components/App/MApp.razor.cs +++ b/src/Masa.Blazor/Components/App/MApp.razor.cs @@ -31,17 +31,6 @@ protected override void OnInitialized() _ = UpsertThemeStyle(MasaBlazor.Theme); } - protected override async Task OnAfterRenderAsync(bool firstRender) - { - await base.OnAfterRenderAsync(firstRender); - - if (firstRender) - { - await OnJSInteropReadyAsync(); - StateHasChanged(); - } - } - private void OnStateChanged(object? sender, EventArgs e) { InvokeAsync(StateHasChanged); @@ -57,11 +46,6 @@ private void OnDefaultsChanged(object? sender, EventArgs e) InvokeAsync(StateHasChanged); } - private async Task OnJSInteropReadyAsync() - { - await MasaBlazor.Breakpoint.InitAsync(Js); - } - private void OnThemeChange(Theme theme) { InvokeAsync(async () => diff --git a/src/Masa.Blazor/Core/MasaComponentBase.cs b/src/Masa.Blazor/Core/MasaComponentBase.cs index f43ee1ce79..b096370b34 100644 --- a/src/Masa.Blazor/Core/MasaComponentBase.cs +++ b/src/Masa.Blazor/Core/MasaComponentBase.cs @@ -14,6 +14,8 @@ protected MasaComponentBase() [Inject] public IJSRuntime Js { get; set; } = null!; [Inject] private ILoggerFactory LoggerFactory { get; set; } = null!; + + [Inject] private MasaBlazor MasaBlazor { get; set; } = null!; [CascadingParameter] protected IDefaultsProvider? DefaultsProvider { get; set; } @@ -232,6 +234,15 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); + // Before the interactive component publishing released by Blazor in .NET 8.0, + // only need to initialize the breakpoint service in the root component (MApp). + // But after the interactive component publishing, + // need to try to initialize the breakpoint service in each component. + if (firstRender) + { + MasaBlazor.Breakpoint.Init(Js); + } + // TODO: is this necessary? if (_elementReferenceChanged) { diff --git a/src/Masa.Blazor/Services/Breakpoint/Breakpoint.cs b/src/Masa.Blazor/Services/Breakpoint/Breakpoint.cs index b156a6b11e..0fc1017231 100644 --- a/src/Masa.Blazor/Services/Breakpoint/Breakpoint.cs +++ b/src/Masa.Blazor/Services/Breakpoint/Breakpoint.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using Masa.Blazor.Utils; namespace Masa.Blazor; @@ -13,11 +14,8 @@ public class BreakpointOptions public class Breakpoint { - public Breakpoint() - { - } - - private IJSRuntime? JSRuntime { get; set; } + private readonly Throttle _throttle = new(500); + private IJSRuntime? _jsRuntime; /// /// Indicates that the breakpoint has been calculated. If not, the breakpoint will not work. @@ -104,15 +102,23 @@ public void Deconstruct( mobileBreakpoint = MobileBreakpoint; } - public async Task InitAsync(IJSRuntime jsRuntime) + public void Init(IJSRuntime jsRuntime) { - JSRuntime = jsRuntime; + _throttle.Execute(() => + { + if (_jsRuntime is not null) + { + return; + } + + _jsRuntime = jsRuntime; - await ResizeAsync(); + _ = ResizeAsync(); - _ = JSRuntime.AddHtmlElementEventListener("window", "resize", ResizeAsync, - new EventListenerOptions { Passive = true }, - new EventListenerExtras(debounce: 200)); + _ = _jsRuntime.AddHtmlElementEventListener("window", "resize", ResizeAsync, + new EventListenerOptions { Passive = true }, + new EventListenerExtras(debounce: 200)); + }); } private async Task ResizeAsync() @@ -207,12 +213,12 @@ private async Task GetClientSizeAsync(string sizeName) private async Task GetNumberPropAsync(string selector, string name) { - if (JSRuntime is null) + if (_jsRuntime is null) { - throw new NullReferenceException("JSRuntime is null. Please call UpdateJsRuntime(IJSRuntime jsRuntime) first."); + throw new NullReferenceException("JSRuntime is not initialized."); } - var jsonElement = await JSRuntime.InvokeAsync(JsInteropConstants.GetProp, selector, name); + var jsonElement = await _jsRuntime.InvokeAsync(JsInteropConstants.GetProp, selector, name); return jsonElement.ValueKind == JsonValueKind.Number ? jsonElement.GetDouble() : null; } } \ No newline at end of file diff --git a/src/Masa.Blazor/Utils/Throttle.cs b/src/Masa.Blazor/Utils/Throttle.cs new file mode 100644 index 0000000000..d1aa6ff6b9 --- /dev/null +++ b/src/Masa.Blazor/Utils/Throttle.cs @@ -0,0 +1,24 @@ +namespace Masa.Blazor.Utils; + +public class Throttle(TimeSpan delay) +{ + private DateTime _lastExecutionTime = DateTime.MinValue; + private readonly object _lock = new(); + + public Throttle(int delay) : this(TimeSpan.FromMilliseconds(delay)) + { + } + + public void Execute(Action action) + { + lock (_lock) + { + var now = DateTime.UtcNow; + if (now - _lastExecutionTime >= delay) + { + _lastExecutionTime = now; + action(); + } + } + } +} \ No newline at end of file