Reproduceable example: https://blazorrepl.telerik.com/QSEganvg12BVw2ZU37
Steps to reproduce:
If you remove the GridAggregates emtpy render fragment, or put at least one GridAggregate component in it, OnStateInit fires like expected.
In my project, I've created a component that wraps around the TelerikGrid that I use on all my pages, so that I can have many properties and functions set to reasonable defaults for my use case. My component has an option to conditionally include GridAggregate components within the inner TelerikGrid's GridAggregates render fragment based on separate configuration. If no separate configuration is provided, no GridAggregate components are included, and the GridAggregates render fragment is left blank. Since my component is built in razor markup, there isn't a great option for nulling out that render fragment if it's empty. I had no problems with this exact same code in UI for Blazor version 5.1, and I hope this can be fixed.
Hello Michael,
Thank you for coming back with feedback.
As an update about the item, I can confirm that the fix is already in development and it is planned to be shipped in our next release.
I hope the information provided will serve as a good reference for you.
Regards,
Tsvetomir
Progress Telerik
Hello, Michael and everyone affected by this bug,
I apologize for mistakingly marking this bug as a duplicate of the Grid with aggregates never loads if data comes asynchronously regression. The regression masked this bug and we did not cover this scenario. I can confirm that this is a valid bug and our team is already looking into it. Below, I have added a possible workaround where you define the <GridAggregates> tag conditionally. The Conditional Grid ToolBar and DetailTemplate Knowledge-Based article inspire this workaround.
@using Telerik.DataSource
@using Telerik.DataSource.Extensions
<TelerikGrid TItem="@Employee"
OnRead="@ReadItems"
Groupable="true"
FilterMode="@GridFilterMode.FilterRow"
Sortable="true"
OnStateInit="@( (GridStateEventArgs<Employee> args) => OnGridStateInit(args) )"
Pageable="true"
GridAggregates="@( HasAggregates ? GridAggregatesTemplate : null )">
<GridColumns>
<GridColumn Field=@nameof(Employee.Name) FieldType="@(typeof(string))" Groupable="false" />
<GridColumn Field=@nameof(Employee.Team) FieldType="@(typeof(string))" Title="Team">
<GroupHeaderTemplate>
@context.Value @* the default text you would get without the template *@
<span>Team size: @context.Count</span>
</GroupHeaderTemplate>
<GroupFooterTemplate>
Team Members: <strong>@context.Count</strong>
</GroupFooterTemplate>
</GridColumn>
<GridColumn Field=@nameof(Employee.IsOnLeave) FieldType="@(typeof(bool))" Title="On Vacation" />
</GridColumns>
</TelerikGrid>
@code {
private bool HasAggregates { get; set; } = false;
private RenderFragment GridAggregatesTemplate { get; set; } = __builder =>
{
// The content of the <GridAggregates> tag goes here
};
public List<Employee> SourceData { get; set; }
private async Task OnGridStateInit(GridStateEventArgs<Employee> args)
{
// Sort by Stock
args.GridState.SortDescriptors.Add(new SortDescriptor()
{
Member = nameof(Employee.Name),
SortDirection = ListSortDirection.Descending
});
args.GridState.GroupDescriptors.Add(new GroupDescriptor()
{
Member = nameof(Employee.Team),
MemberType = typeof(string)
});
}
// Handling grouping happens here - by casting the DataSourceResult.Data to objects
protected async Task ReadItems(GridReadEventArgs args)
{
// in this example, we use the Telerik extension methods to shape the data
// you can, instead, call a service, read more in the following example projects
// https://github.com/telerik/blazor-ui/tree/master/grid/datasourcerequest-on-server
var datasourceResult = SourceData.ToDataSourceResult(args.Request);
// to work with grouping, the grid data needs to be an IEnumerable<object>
// because grouped data has a different shape than non-grouped data
// and this is, generally, hidden from you by the grid, but now it cannot be
args.Data = datasourceResult.Data.Cast<object>().ToList();
args.Total = datasourceResult.Total;
args.AggregateResults = datasourceResult.AggregateResults;
}
protected override async Task OnInitializedAsync()
{
SourceData = GenerateData();
}
private List<Employee> GenerateData()
{
var result = new List<Employee>();
var rand = new Random();
for (int i = 1; i <= 15; i++)
{
result.Add(new Employee()
{
EmployeeId = i,
Name = "Employee " + i.ToString(),
Team = "Team " + i % 3,
IsOnLeave = i % 2 == 0
});
}
return result;
}
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Team { get; set; }
public bool IsOnLeave { get; set; }
}
}Regards,
Tsvetomir
Progress Telerik