I implemented a custom DataAdaptor to load data from a remote source, but I couldn't find any debounce support in the AutoComplete component.
Given that a remote request is issued at every key, it looks expensive, to me, in case of remote requests. My feeling is that there's some debounce time anyway, internally (because if you type very quickly, you can see less calls than the actual typed characters), but it would be nice if this value could be configurable.
Thank you.
|
<SfAutoComplete @ref="AutoCompleteObj" TValue="string" TItem="Countries" Placeholder="e.g. Australia" DataSource="@LocalData">
<AutoCompleteFieldSettings Value="Name"></AutoCompleteFieldSettings>
<AutoCompleteEvents TValue="string" TItem="Countries" Filtering="onInputDebounced"></AutoCompleteEvents>
</SfAutoComplete>
@code {
SfAutoComplete<string, Countries> AutoCompleteObj;
public class Countries
{
public string Name { get; set; }
public string Code { get; set; }
}
List<Countries> LocalData = new List<Countries> {
new Countries() { Name = "Australia", Code = "AU" },
new Countries() { Name = "Bermuda", Code = "BM" },
new Countries() { Name = "Canada", Code = "CA" },
new Countries() { Name = "Cameroon", Code = "CM" },
new Countries() { Name = "Denmark", Code = "DK" }
};
public void onFiltering(Syncfusion.Blazor.DropDowns.FilteringEventArgs args)
{
args.PreventDefaultAction = true;
var query = new Query();
if (args.Text != "")
{
query = new Query().Where(new WhereFilter()
{
Field = "Name",
value = args.Text,
Operator = "Contains",
IgnoreCase = true
});
}
this.AutoCompleteObj.Filter(LocalData, query);
}
Action<Syncfusion.Blazor.DropDowns.FilteringEventArgs> onInputDebounced;
protected override void OnInitialized()
{
onInputDebounced = DebounceEvent<Syncfusion.Blazor.DropDowns.FilteringEventArgs>(e => this.onFiltering(e), TimeSpan.FromMilliseconds(300));
base.OnInitialized();
}
Action<T> DebounceEvent<T>(Action<T> action, TimeSpan interval)
{
return Debounce<T>(arg =>
{
InvokeAsync(() =>
{
action(arg);
StateHasChanged();
});
}, interval);
}
Action<T> Debounce<T>(Action<T> action, TimeSpan interval)
{
if (action == null) throw new ArgumentNullException(nameof(action));
var last = 0;
return arg =>
{
var current = System.Threading.Interlocked.Increment(ref last);
Task.Delay(interval).ContinueWith(task =>
{
if (current == last)
{
action(arg);
}
});
};
}
}
|
:-) It's a nice piece of code, but it's not my case. I adapted it to work with my custom remote adapter, but the filtering happens after data is loaded from the server, so it doesn't change the remote behavior (if I adapted the code to my case correctly).
Andrea Bioli
Sorry, reading better the code, I think I understand now the principle, and the workflow.
I remain with the problem of having my Autocomplete object built in the following way:
<SfAutoComplete @ref="AutoCompleteObj" TValue="string" TItem="LookupValue" Placeholder="...start typing to search">
<SfDataManager AdaptorInstance="@typeof(TEntity)" Adaptor="Adaptors.CustomAdaptor"></SfDataManager>
<AutoCompleteFieldSettings Value="Description" />
<AutoCompleteEvents TValue="string" TItem="LookupValue" ValueChange="onChange" Filtering="onInputDebounced"></AutoCompleteEvents>
</SfAutoComplete>
(formatting is not good, sorry)
And the last line of onFiltering takes data from a local variable. Where can I find what's returned from the CustomAdaptor (that by the way is already filtered with the text...).
Thank
I'm making progresses.
Now, using the debouncing, I can see that (after the first run, where for each key there is a remote call, very strange), with a very high debouncing time (2000 milliseconds) the remote calls are done with that interval.
This is the code for my (remote custom adaptor) case:
private void onFiltering(FilteringEventArgs args)
{
args.PreventDefaultAction = true;
var query = new Query();
if (args.Text != "")
{
query = new Query().Where(new WhereFilter()
{
Field = "Name",
value = args.Text,
Operator = "Contains",
IgnoreCase = true
});
}
this.AutoCompleteObj.Filter(this.AutoCompleteObj.DataSource, query); // <-- modified call
}
But I still have a weird case, where there is no refresh of the drop down list after each call.
You can see in the picture that there is a content in the input box, but the drop down list still shows the result of the previous, and so on.
Is there some code I can execute to refresh the list?
Thanks again.
Andrea Bioli
P.S.: I cannot upload the zipped picture, I don't know why: I hope you can get the point anyway...