I have built my own component, GenericGrid, which under the hood uses a TelerikGrid. The GenericGrid takes TItem as typeparam which gets passed onto a generic HTTP method that retrieves records from an OData API based on the TItem that gets passed on.
GenericGridTest.razor:
@page "/GenericGrid"
@using IndiciaStage.Domain.Entities
<GenericGrid TItem="Employee"></GenericGrid>
@code
{
}
GenericGrid.razor:
@using Indicia.Grid.Services
@using System.Collections.ObjectModel
@using IndiciaStage.Domain.Entities
@inject LocalStorageService _localStorage
@inject GenericHttpEntityService _entityService
@typeparam TItem
<TelerikGrid @ref="@Grid"
AutoGenerateColumns="true"
Height="460px"
RowHeight="60"
PageSize="10"
Pageable="true"
Sortable="true"
Resizable="true"
FilterMode="GridFilterMode.FilterMenu"
EditMode="GridEditMode.Popup"
OnRead="@ReadEntity"
OnStateInit="@((GridStateEventArgs<object> args) => OnStateInitHandler(args))"
OnStateChanged="@((GridStateEventArgs<object> args) => OnStateChangedHandler(args))">
<GridColumns>
<GridAutoGeneratedColumns />
</GridColumns>
</TelerikGrid>
@code {
// Grid data
private List<TItem> GridData { get; set; } = new();
private int Total { get; set; }
// Parameters
[Parameter]
public TItem Entity { get; set; }
private async Task ReadEntity(GridReadEventArgs args)
{
var data = await _entityService.GetAll<TItem>(args.Request);
GridData = data.Records;
Total = data.Total;
StateHasChanged();
}
EntityListResponse.cs (based on the OData Grid sample on GitHub, made generic):
public class EntityListResponse<T>
{
[System.Text.Json.Serialization.JsonPropertyName("value")]
public List<T> Records { get; set; }
[System.Text.Json.Serialization.JsonPropertyName("@odata.count")]
public int Total { get; set; }
}
GetAll method in GenericHttpEntityService.cs:
public async Task<EntityListResponse<T>> GetAll<T>(DataSourceRequest request)
{
var name = typeof(T).Name;
var baseUrl = $"{name}s?";
var requestUrl = $"{baseUrl}{request.ToODataString()}";
var requestMessage = new HttpRequestMessage(HttpMethod.Get, requestUrl);
requestMessage.Headers.Add("Accept", "application/json");
var client = HttpClient.CreateClient("IndiciaStageApi");
var response = await client.SendAsync(requestMessage);
if (response.IsSuccessStatusCode)
{
var body = await response.Content.ReadAsStringAsync();
var options = new JsonSerializerOptions();
options.Converters.Add(new JsonStringEnumConverter());
var oDataResponse = JsonSerializer.Deserialize<EntityListResponse<T>>(body, options);
return oDataResponse;
}
else
{
throw new HttpRequestException(
"Request failed. I need better error handling, e.g. returning empty data.");
}
}
What I want to achieve is for the grid columns to be generated automatically based on the object type, Employee in this case, and the retrieved data to be bound to the grid. Sadly, this doesn't seem to work
As you can see, the JSON is deserialized correctly into an EntityListResponse of type Employee. However, I don't know how to bind the data to the grid and autogenerate its corresponding columns. I tried adding Data="@GridData" to the TelerikGrid, but that returns an error because the type of GridData is List<TItem>.
Is there any way to implement what I'm trying to achieve?