|
<SfComboBox TValue="string" TItem="Order" Placeholder="Click Me" CssClass="e-outline">
<SfDataManager Adaptor="Adaptors.CustomAdaptor">
<FetchData></FetchData>
</SfDataManager>
<ComboBoxFieldSettings Text="CustomerID" Value="CustomerID"></ComboBoxFieldSettings>
</SfComboBox>
<SfMultiSelect TValue="string[]" ModelType="@typeof(Order)" Placeholder="Click Me Multiple" Mode="VisualMode.CheckBox" CssClass="e-outline">
<SfDataManager Adaptor="Adaptors.CustomAdaptor">
<FetchData></FetchData>
</SfDataManager>
<MultiSelectTemplates>
<ItemTemplate>
<span title="@((context as Order).CustomerID)">@((context as Order).CustomerID)</span>
</ItemTemplate>
<ValueTemplate>
<span title="@((context as Order).CustomerID)">@((context as Order).CustomerID)</span>
</ValueTemplate>
<NoRecordsTemplate>
<span>No Values Found</span>
</NoRecordsTemplate>
<ActionFailureTemplate>
<span>Failed Loading Values</span>
</ActionFailureTemplate>
</MultiSelectTemplates>
<MultiSelectFieldSettings Value="CustomerID"></MultiSelectFieldSettings>
</SfMultiSelect>
@code{
public class Order
{
public int OrderID { get; set; }
public string CustomerID { get; set; }
public double Freight { get; set; }
}
}
FetchData:
@inherits DataAdaptor
<CascadingValue Value="@this">
@ChildContent
</CascadingValue>
@code {
public static IEnumerable<Order> Orders { get; set; }
protected override void OnInitialized()
{
Orders = Enumerable.Range(1, 75).Select(x => new Order()
{
OrderID = 1000 + x,
CustomerID = (new string[] { "ALFKI", "ANANTR", "ANTON", "BLONP", "BOLID" })[new Random().Next(5)],
Freight = 2.1 * x,
}).ToList();
}
[Parameter]
[JsonIgnore]
public RenderFragment ChildContent { get; set; }
private IEnumerable<Order> _listItems;
//private Order<Order> _list { get; set; }
//[Parameter]
//public IHttpClientResponseMocker ResponseMocker { get; set; }
//[Parameter]
//public FormTemplateFieldList ListField { get; set; }
//[Parameter]
//public FormFieldComponent ParentComponent { get; set; }
public async override Task<object> ReadAsync(DataManagerRequest dataManagerRequest, string key = null)
{
try
{
//if (_list == null)
//{
// _list =
// await ListService.RetrieveAsync<GenericList<GenericListValue>, GenericListValue>(ResponseMocker,
// ListField.ListDomain, ListField.ListId);
// _listItems = _list.Values.ToArray();
//}
await Task.Delay(100);
var DataSource = Orders;
if (dataManagerRequest.Search != null && dataManagerRequest.Search.Count > 0)
{
DataSource = DataOperations.PerformSearching(DataSource, dataManagerRequest.Search);
}
if (dataManagerRequest.Sorted != null && dataManagerRequest.Sorted.Count > 0)
{
DataSource = DataOperations.PerformSorting(DataSource, dataManagerRequest.Sorted);
}
if (dataManagerRequest.Where != null && dataManagerRequest.Where.Count > 0)
{
DataSource = DataOperations.PerformFiltering(DataSource, dataManagerRequest.Where, dataManagerRequest.Where[0].Operator);
}
if (dataManagerRequest.Skip != 0)
{
DataSource = DataOperations.PerformSkip(DataSource, dataManagerRequest.Skip);
}
if (dataManagerRequest.Take != 0)
{
DataSource = DataOperations.PerformTake(DataSource, dataManagerRequest.Take);
}
Console.WriteLine($"DataSource count: {DataSource.Count()}");
return (dataManagerRequest.RequiresCounts ? new DataResult() { Result = DataSource, Count = DataSource.Count() } : (object)DataSource);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
throw;
}
}
} |
I know it's loaded in a synchronous manner - I mentioned that in my previous post as the cause for the problem.
That doesn't mean that the way the adaptor works is valid from an engineering point of view.
When I call the service to retrieve data, I don't know in advance if the call will complete in a synchronous manner or not (e.g. if it will get a cache hit or cache moss and in turn will make a call to the server) - therefore the option of using Read is not a valid one.
Async methods do not guarantee a consistent way of executing (sync vs. async completion) and using Task.Delay as a workaround is a patch that should not exist normally in production code.
Can you please run this by your engineering team? We can sweep this under the rug and other developers will keep running into the same issue since the adaptor component does not adhere to the async development paradigm (unless you can show me that I'm doing something that should not be done from a pure C# perspective) or you can simply fix this behavior and save us the need to introduce garbage code and permanent unwanted patches into our products.
Thank you.
Koby