using System; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; using AntDesign.Core.Extensions; namespace AntDesign { public abstract class AntComponentBase : ComponentBase, IDisposable { [Parameter] public ForwardRef RefBack { get; set; } = new ForwardRef(); private readonly Queue> _afterRenderCallQuene = new Queue>(); protected void CallAfterRender(Func action) { _afterRenderCallQuene.Enqueue(action); } protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); if (firstRender) { await OnFirstAfterRenderAsync(); } if (_afterRenderCallQuene.Count > 0) { var actions = _afterRenderCallQuene.ToArray(); _afterRenderCallQuene.Clear(); foreach (var action in actions) { if (IsDisposed) { return; } await action(); } } } protected virtual Task OnFirstAfterRenderAsync() { return Task.CompletedTask; } protected AntComponentBase() { } protected void InvokeStateHasChanged() { InvokeAsync(() => { if (!IsDisposed) { StateHasChanged(); } }); } protected async Task InvokeStateHasChangedAsync() { await InvokeAsync(() => { if (!IsDisposed) { StateHasChanged(); } }); } [Inject] protected IJSRuntime Js { get; set; } protected async Task JsInvokeAsync(string code, params object[] args) { try { return await Js.InvokeAsync(code, args); } catch (Exception e) { throw; } } protected async Task JsInvokeAsync(string code, params object[] args) { try { await Js.InvokeVoidAsync(code, args); } catch (Exception e) { Console.WriteLine(e); throw; } } /// /// Standard Focus. From Net5 uses Blazor extension method on ElementReference. /// Before, uses JS implemented exactly the same as Net5 JS. /// /// Element that will receive focus. /// Whether to scroll to focused element protected async Task FocusAsync(ElementReference target, bool preventScroll = false) => await Js.FocusAsync(target, preventScroll); /// /// Focus with behaviors. Behavior will work only for elements that are /// HTMLInputElement or HTMLTextAreaElement. Otherwise will only focus. /// /// Element that will receive focus. /// Behavior of focused element /// Whether to scroll to focused element protected async Task FocusAsync(ElementReference target, FocusBehavior behavior, bool preventScroll = false) => await Js.FocusAsync(target, behavior, preventScroll); /// /// Standard Blur. Uses JS interop. /// /// Element that will receive focus. protected async Task BlurAsync(ElementReference target) => await Js.BlurAsyc(target); protected bool IsDisposed { get; private set; } protected virtual void Dispose(bool disposing) { if (IsDisposed) return; IsDisposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~AntComponentBase() { // Finalizer calls Dispose(false) Dispose(false); } } }