Примерно так:
@inject DbContext dbContext; // your EF DbContext to access your data
<datalist id="suggestions">
@foreach (var b in filteredList)
{
<option value="@b.Value">@b.Text</option>
}
</datalist>
<input autoComplete="on" list="suggestions" value="@theValueEntered"
@oninput="OnInputChanged"
@onfocus='() => OnInputChanged(new ChangeEventArgs { Value = "" })'/>
@code {
private string theValueEntered;
private IEnumerable<Data> filteredList;
private async Task OnInputChanged(ChangeEventArgs e)
{
theValueEntered = e.Value as string;
filteredList = await dbContext.Data
.Where(x => x.Name.StartWith(theValueEntered)
.Take(50)
.ToListAsync()
.ConfigureAwait(false);
StateHasChanged();
}
}
Если вы хотите ограничить количество запросов к вашей базе данных, вы можете использовать Task.Delay
// with the same html code
@inject IServiceProvider provider; // get a provider instance
@code {
private CancellationTokenSource cancellationTokenSource;
private string theValueEntered;
private IEnumerable<Data> filteredList;
private Task OnInputChanged(ChangeEventArgs e)
{
theValueEntered = e.Value as string;
cancellationTokenSource?.Cancel();
cancellationTokenSource?.Dispose();
cancellationTokenSource = new CancellationTokenSource();
var token = _cancellationTokenSource.Token;
return Task.Delay(250, token)
.ContinueWith(async task =>
{
if (task.IsCanceled)
{
return;
}
using var scope = provider.CreateScope();
var context = scope.GetRequiredService<DbContext>();
filteredList = await context.Data
.Where(x => x.Name.StartWith(theValueEntered)
.Take(50)
.ToListAsync()
.ConfigureAwait(false);
await InvokeAsync(StateHasChanged);
}, TaskScheduler.Default);
}
}