Megabit / Blazorise

Blazorise is a component library built on top of Blazor with support for CSS frameworks like Bootstrap, Tailwind, Bulma, AntDesign, and Material.
https://blazorise.com/
Other
3.26k stars 529 forks source link

Blazorise.Datagrid - Get Current Values from RowInserting & RowUpdating #2402

Closed dudley810 closed 3 years ago

dudley810 commented 3 years ago

On RowInserting and RowUpdating I am having an issue getting the current object values keyed in the form to send to the API.

I can only do it like this for both rowinserting and rowupdating protected async Task RowInserting(CancellableRowChange<WeatherForecast, Dictionary<string, object>> e) { WeatherForecast u = new WeatherForecast(); u.Date = (string)e.Values["Date"]; //IS THERE A EASIER WAY TO GET THE CURRENT VALUES u.TemperatureC = (string)e.Values["TemperatureC"]; //IS THERE A EASIER WAY TO GET THE CURRENT VALUES u.TemperatureF = (string)e.Values["TemperatureF"]; //IS THERE A EASIER WAY TO GET THE CURRENT VALUES u.Summary = (string)e.Values["Summary"]; //IS THERE A EASIER WAY TO GET THE CURRENT VALUES

SOLUTION Have one object that would already be all the values like the e.item.

I created a tester that is how I believe you would need to code a cancel with a form that would work when the user gets an error. This way if there is an error they would fix the issue and hit save again. Let me know if there is a better way to get the current values.

https://github.com/dudley810/gridtest

stsrki commented 3 years ago

There is no other way than to use dictionary values. Having something like an e.item would mean to be able to deep clone the object, and that is difficult with complex objects. Not to mention when there are nested objects inside of the model.

Also, yoi almost never edit all fields in the model. Most of the time you edit only some field. That is why a dictionary is used. To hold only the edited values, and to not keep reference to the original model. Otherwise, weird stuff would happen.

dudley810 commented 3 years ago

K I get you -- so do you normally just use the useinternalediting false then have them rekey the data if there was an issue? Cause other than rekeying the data I could not figure out how to use these two events. I created this code in the EventArguments.cs and it seems to work but not sure about the nested objects.

    public TItem GetCurrentScreen()
    {
        object obj = JsonSerializer.Deserialize<TItem>(JsonSerializer.Serialize(this.Item));
        PropertyInfo[] prop = obj.GetType().GetProperties();
        foreach (KeyValuePair<string, object> kv in this.Values as Dictionary<string, object>)
        {
            PropertyInfo pi = (from p in prop where p.Name == kv.Key select p).FirstOrDefault<PropertyInfo>();
            pi.SetValue(obj, kv.Value);
        }
        return (TItem)obj;
    }
stsrki commented 3 years ago

For nested objects you will probably need to use recursion and determine how to get the property of the nested value.

If it can help you, look at our code for reference. There you can find some reflection code for accessing nested fields.

https://github.com/Megabit/Blazorise/blob/master/Source/Extensions/Blazorise.DataGrid/Utils/FunctionCompiler.cs