Hi,
When I change the DataSource of an SfGrid (one that may have different columns) it does not display the new data. Minimal repro provided below:
@page "/"
@using Syncfusion.Blazor.Popups
@using System.Dynamic
@using Syncfusion.Blazor.Grids
@using Syncfusion.Blazor.Buttons
<SfButton Content="Generate new data" OnClick=@OnGenerateNewData />
<SfGrid
@ref="grid"
Height="400px"
Width="100%"
TValue="ExpandoObject"
DataSource=@data>
</SfGrid>
@code{
private SfGrid<ExpandoObject> grid;
private List<ExpandoObject>? data = GenerateNewData();
public void OnGenerateNewData()
{
this.data = GenerateNewData();
// grid?.Refresh(); // this doesn't work either
}
private static List<ExpandoObject> GenerateNewData()
{
var data = new List<ExpandoObject>();
var random = new Random();
var colCount = random.Next(2, 6);
var colNames = new string[colCount];
for(var col = 0; col < colCount; col++)
{
colNames[col] = "Col" + random.Next(0, 5000);
}
for (var row = 0; row < 100; row++)
{
dynamic item = new ExpandoObject();
var dict = (IDictionary<string, object>)item;
for (var col = 0; col < colCount; col++)
{
dict[colNames[col]] = random.Next(0, 10000);
}
data.Add(item);
}
return data;
}
}
|
@if (RenderGrid)
{
<SfGrid
@ref="grid"
Height="400px"
Width="100%"
TValue="ExpandoObject"
DataSource=@data>
</SfGrid>
}
public bool RenderGrid = true;
public async Task OnGenerateNewData()
{
RenderGrid = false;
await Task.Yield();
this.data = GenerateNewData();
RenderGrid = true;
//grid?.Refresh(); // this doesn't work either
}
|
The workaround you provided does work, thank you. However, we think this is a serious bug that needs be fixed, over and above the temporary workaround.
For example, without the fix, we have had instances which are much more subtle than our repro code, where the data is shown with incorrect headers, but other than that it looks ok. For some applications this could be dangerous.
Please consider a bug fix for when the datasource has changed.
Regards, John
|
<SfGrid @ref="grid"
Height="400px"
Width="100%"
TValue="ExpandoObject"
DataSource=@data>
<GridColumns>
@if (data != null && data.Any())
{
var firstItem = data.First();
var dictionaryItem = (IDictionary<string, object>)firstItem;
var fields = dictionaryItem.Keys;
foreach (var item in dictionaryItem)
{
<GridColumn Field="@item.Key"></GridColumn>
}
}
</GridColumns>
</SfGrid> |
I completely agree with John... I've read about six or seven different posts on this same issue. I've tried your "fixes" for all of them and so far none of them... including both of the ones that you have posted on this page has worked. All these hackish steps are not a resolution. You should find a way to resolve this issue within the grid.Refresh(); method.
In my case my Grid happens to be within tabs... I've noticed when I click on a different tab and back the grid refreshes so it seems to be an issue with refreshing the UI.
Hi Anthony,
We are currently validating the query at our end and we need some more time to analyze this issue and we will update further details within two business days.
Until then we appreciate your patience.
Regards,
Monisha
Hi Anthony,
Thanks for the patience.
Query: “You should find a way to resolve this issue within the grid.Refresh(); method.”
We understand your suggestion but, calling the refresh method will update the grid data only when there are changes in the data alone (no changes in column name ). But the calling method will not work when data along with different column names are assigned dynamically. In this scenario, the suggestion provided in this update will resolve the reported query.
If you are still facing an issue with it. Kindly get back to us with more details.
Query: “ I've noticed when I click on a different tab and back the grid refreshes so it seems to be an issue with refreshing the UI.”
We need some more details about the issue you are facing. So kindly share the following details to validate the issue further at our end.
The above-requested details will be very helpful for us to validate
the reported query at our end and provide a solution as early as possible.
Regards,
Vignesh Natarajan
This issue also affects my current use case.
You shouldn't even have to call refresh, when a new data source is provided to the sfgrid component it should re-render itself accordingly based on the expectation that it is dynamically occurring.
The suggested solutions are not solutions at all. Stop pushing back BS code changes on your end users. Telerik is always nipping at your heels guys.
Ultimately, do better Syncfusion.
The only real work around that I've found for this syncfusion BUG is to use a renderFragment approach.
Instead of adding the sfgrid component explicitly to the razor markup you can render the component with a call like this. The renderGridToggle forces a new Frame in the builder tree which actually makes the syncfusion component rerender with new columns when you change the dynamic data source.
Skeleton Component...
@page "/dynamicGrid"
@using Syncfusion.Blazor.Grids
@renderGrid()
@code{
private bool renderGridToggle;
public List<ExpandoObject> ExpandoRecords { get; set; } = new List<ExpandoObject>();
public RenderFragment renderGrid() => builder =>
{
ExpandoRecords = [GET YOUR DATA HERE];
renderGridToggle = !renderGridToggle;
var type = typeof(SfGrid<ExpandoObject>);
builder.OpenComponent(Convert.ToInt32(renderGridToggle), type);
builder.AddAttribute(1, "DataSource", ExpandoRecords);
builder.CloseComponent();
};
}
Before proceeding further with your requirement. kindly share the below details will be very helpful for us to validate the reported query at our end and provide the solution as early as possible.
@John. In your first example, this will not work as the column names are changed for each generation and the grid will be empty, because the column binding is not working. I would not call this a bug, but more "by design", to make rendering the grid more efficient and only use the Refresh for data changes.
As SyncFusion suggests, you could re-render the entire component, if you want to change columns at runtime (fx using a flag). This will generate the new bindings.
You could wrap this in a component, then implement a public reference in there for a RefreshColumnsAndData() method, then our component can take care of the column re-rendering for you in the normal page cycle. Easy and only requires a few lines of extra code.
Hi Parben,
Thanks for the additional information.
We are also having problems with grid rerendering in a customer service project with changing status by multiple operators. Records updated by one operator are not reflected in other operators' grids (with a grid refresh timer).
Hi Rogerio,
Before proceeding further kindly share us some more details about your requirement.
The above requested details will be very helpful for us to validate the reported issue at our end.
Regards,
Monisha