I'm stroring grid's settings using @bind-Settings to app's client state. Now, after i filter the grid with one or more columns, saved state is updated and looks "ok", that means columns array contains columns and those with filter have it set.
However, when i return back to component, settings get loaded (brakepoint is being hit...), still looks "ok", grid is rendered with filters set, so visually everything looks right. After that LoadData event get dispatched and it does not contains any filters, which of course results in loading data without filters.
I'm probably doing something wrong, but i'm not sure what
I'm trying to create my own "default" typed datagrid component, which basically means that my component contains instance of component RadzenDataGrid with many attributes set to my prefered values and few parameters.
Shortened important parts are as follows:
@typeparam T
<RadzenDataGrid
TItem="@T"
Data="@data"
Count="@dataTotal"
LoadData="@OnLoadData"
@bind-Settings="@MySettings"
...
>
...
</RadzenDataGrid>
@code {
[Parameter] public Func<LoadDataArgs, Task<ListWithTotalCount<T>>>? DataLoader { get; set; }
[Parameter] public EventCallback<DataGridSettings> MySettingsChanged { get; set; }
[Parameter] public DataGridSettings? MySettings {
get => mySettings;
set {
if(mySettings != value)
MySettingsChanged.InvokeAsync(mySettings = value);
}
}
private List<T>? data;
private int dataTotal = 0;
private DataGridSettings? mySettings;
private async Task OnLoadData(LoadDataArgs params)
{
ListWithTotalCount<T>? listWithTotalCount = DataLoader is not null
? await DataLoader.Invoke(params)
: null;
if(listWithTotalCount is not null)
{
data = listWithTotalCount.List;
dataTotal = listWithTotalCount.Total;
}
}
}
Point of all of this is, that I'll reuse my grid component somewhere and just add specific method implementation to DataLoader property and bind to DataGridSettings instance with stored settings. Until i integrated settings, everything worked fine, and can work fine again, as soon as i remove @bind-Settings="@MySettings" (effectively removing settings functionality).
But with settings binding present things start to fall apart. For example:
enum filtering behaves strangely, i can select one of the values in filter dropdown, list will filter, but then i cannot remove or change the dropdown value, i can do it, but nothing happens (even the dropdown won't re-render)
if i set some (text) filter column, data will get filtered but if i navigate out of component and back, filter is set but data won't get filtered
I tried to combine LoadData with Settings examples as you mentioned, and it really works, so i presume, problem is somewhere with Settings binding in my component. What i'm trying to achieve is basically to delegate RadzenDataGrid Settings binding to my component.
With setup like this, when I navigate back to the component I can see that even in OnInitialized event, the private DataGridSettings? mySettings is already populated with settings (and filters). But breakpoint in OnLoadData and its params argument does not reflect those settings (which are still present in mySettings btw).
Now I wasted several hours with trying to debug this... Still no idea why it doesn't work. So I made completely new page, used RadzeDataGrid directly and it works. Next step I did was to get my Grid component which is encapsulating RadzenDataGrid as close as possible to this working example. I honestly think, those two instances are the same as far as i can tell and believe me i spent hours looking at them. Only thing I was able to get out of this was, that when I run working example I'll get following output:
OnLoadDataEvent(LoadDataArgs args)
args.Filters.Count(): 0
MySettings?.Columns.Count(x => x.FilterValue is not null):
OnAfterRenderAsync(firstRender = True)
OnLoadDataEvent(LoadDataArgs args)
args.Filters.Count(): 2
MySettings?.Columns.Count(x => x.FilterValue is not null): 2
But when I'll run my Grid component I'll get this instead:
OnAfterRenderAsync(firstRender = True)
OnLoadDataEvent(LoadDataArgs args) / args.Filters.Count(): 0 / MySettings?.Columns.Count(x => x.FilterValue is not null): 1
So, by entering the component, i won't get the first LoadData event without filters, but I'll get the second one, cause by StateHasChanged() in OnAfterRenderAsync. In the second LoadData event, binded MySettings property already contains filtering data but the args instance does not.
I have no idea, why are these sequences of events different
I am experiencing basically the same issue while using bind-settings and LoadData in a Blazor Server app. I've duplicated the code posted by @enchev and I'm still not able to get the LoadData method to fire with the correct LoadDataArg values. Using the code posted by @enchev, the I get the following sequence of events:
LoadData(LoadDataArgs args) - args contains no filters, sorting, paging, etc.
OnAfterRenderAsync(firstRender = True)
LoadStateAsync()
I would expect LoadData to be called again after the settings have been loaded via LoadStateAsync, but it never does. The datagrid settings appear to be loaded because the grid is showing the correct sorting, filters, and paging, but the data is not correct because LoadData method is not getting called again after the settings have been loaded. I have tried calling grid.Reload() after LoadStateAsync, but the LoadData call's args still do not contain any filters, paging or sorting.
I assume the expected behavior would be for LoadData to be called initially without any LoadDataArgs and then be called again after the bind-settings have been set via LoadStateAsync(). If so, this does not appear to be happening for me.
I would argue, that ideally, LoadData would fire only once, with correct LoadDataArgs, because now, in @enchev 's working example, it's dispatched twice, which means two db queries or API calls. First without desired parameters and second one with correct ones.
But at this point I don't really care about one more DB / API call anymore, I would be happy if I could get my Grid to work at all. That means to actually get the LoadData event with correct parameters.
@ns6000, is LoadData firing the second time for you after you load the settings from localstorage? I agree that LoadData should ideally only fire once, but my plan was to add logic to prevent the initial API call in the first LoadData and only allow it after the grid settings have been set. My problem is that I'm not getting a second LoadData call after loading the settings from localstorage.
@ghck17
As I posted earlier, I'm getting LoadData event only once, after OnAfterRenderAsync, which loads Settings from local storage and calls StateHasChanged.
After more debugging, it appears I am only experiencing my issue when I have a filter applied. I am using advanced filtering and when I have a filter applied, LoadData is not getting called after LoadStateAsync(). With only sorting and paging applied, I'm seeing the expected behavior and everything functions properly. @enchev, can you try applying an advanced filter in your above example and confirm there is not a bug around this? TIA.
Interesting, I can confirm this, as soon as filters are completely disabled, it works. Also I've tried different filter modes and when I'm using Simple filter mode and I'll set filter on column with enums (filter is rendered as dropdown then) to some value, then another filter on decimal column, I can't change or modify the enum filter anymore. I can do it but the change is ignored and dropdown stays at the first choice. But, if I switch to the Advanced filter mode, manipulating filters works as expected, meaning I can set / reset / remove multiple filters and that works, but the LoadData with wrong arguments problem remains.
Here is the same code I've posted in this thread however with advanced filter. LoadData is execute when settings are loaded with proper values for filtering:
I've created new .net 6 WASM project, then i added Radzen, then i took the example from docs, replaced with it default Index component and removed dependency on db and EventConsole component.
Instead, I've added some console logging and LoadData method. Everything works, now only change necessary to make the example stop working competely, is to initialize model to empty list.
So, to change: private IEnumerable<Employee>? employees;
to: private IEnumerable<Employee>? employees = new List<Employee>()
DataGrid will not be reloaded if the list is empty and later filled with data since since nothing will notify that this happened. Changing however the collection assigned to Data property from null to something will reload the DataGrid.
Hello, I am experiencing a similar problem, the grid data loads correctly and the filters are also applied as expected. The problem comes when you make a filtering greater than (>) and save it in settings, when you load the configuration again it generates the error: operator '>' incompatible with operand types Decimal ans Double
@enchev another interesting debug session and i'm able to reproduce the "bug" by just making LoadData asynchronous... In my complete code example of the Index component where I've changed essentialy just this: