@using FoodsharingSiegen.Contracts.Enums @using Microsoft.JSInterop @implements IAsyncDisposable @inject IJSRuntime JSRuntime @code { [Parameter] public List? Prospects { get; set; } [Parameter] public ProspectStateFilter StateFilter { get; set; } [Parameter] public Func? OnDataChanged { get; set; } [Parameter] public EventCallback OnLoadMore { get; set; } [Parameter] public bool IsLoadingMore { get; set; } [Parameter] public bool HasMore { get; set; } [Parameter] public string GridClass { get; set; } = string.Empty; private IJSObjectReference? _module; private DotNetObjectReference? _dotNetHelper; private string _gridId = $"prospect-grid-{Guid.NewGuid():N}"; private bool _isJsBound; private bool _disposed; protected override async Task OnAfterRenderAsync(bool firstRender) { if (_disposed || !firstRender || _isJsBound) return; try { _dotNetHelper ??= DotNetObjectReference.Create(this); _module ??= await JSRuntime.InvokeAsync("import", "./js/prospect-grid.js"); await _module.InvokeVoidAsync("attachScrollLoader", _gridId, _dotNetHelper); _isJsBound = true; } catch (JSDisconnectedException) { // Ignore browser disconnect during teardown. } catch (ObjectDisposedException) { // Ignore late render after the component is being torn down. } } [JSInvokable] public async Task OnScrollNearBottom() { if (OnLoadMore.HasDelegate && !IsLoadingMore && HasMore) { await OnLoadMore.InvokeAsync(); } } public async ValueTask DisposeAsync() { _disposed = true; if (_module is not null) { try { await _module.InvokeVoidAsync("disposeScrollLoader", _gridId); } catch (JSDisconnectedException) { // ignored; the circuit is already disconnected } catch (ObjectDisposedException) { // ignored; the JS runtime is already disposed } } _dotNetHelper?.Dispose(); _dotNetHelper = null; _isJsBound = false; } }
@(Prospects?.Count ?? 0) Ergebnisse
@if (Prospects?.Any() == true) {
@foreach (var prospect in Prospects) { } @if (IsLoadingMore) {
Weitere laden...
}
}