In continuation of this post I face a problem when cloning an object by serializing/deserializing it with Newtonsoft.Json.
The purpose:
From a list of ItemView
's I'm passing a ItemView
parameter to a dialog/modal component with an EditForm.
If the user clicks the Cancel-button and the dialog closes I must "reset" the parameter so that any unsaved changes in the form is not reflected in the parent list.
Therefore, in my OnInitializedAsync
, I'm cloning the parameter to an ItemViewClone
object so that I can set ItemView = ItemViewClone
when the user cancels the form.
Models:
public class Item
{
public Guid Id { get; set; }
public string Title { get; set; }
}
public class ItemView
{
public Item Item { get; set; }
public int Foo { get; set; }
public double Bar { get; set; }
}
Extension / cloning:
public static class Extensions
{
public static T Clone<T>(this T source)
{
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source , new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Serialize, PreserveReferencesHandling = PreserveReferencesHandling.Objects }));
}
}
Blazor component:
<div class="modal-container">
<div class="modal">
<EditForm Model="@ItemView" OnValidSubmit="SaveForm">
<p><input type="text" @bind="@ItemView.Item.Title" /></p>
<p><input type="button" @onclick="Cancel" value="Cancel" /><input type="submit" value="Save" /></p>
</EditForm>
</div>
</div>
@code {
[Parameter]
public EventCallback<ItemView> Callback { get; set; }
[Parameter]
public ItemView ItemView { get; set; } = new();
public ItemView ItemViewClone { get; set; } = new();
protected override async Task OnInitializedAsync()
{
ItemViewClone = ItemView.Clone(); // Or:
ItemViewClone.Item = ItemView.Item.Clone();
}
async Task Cancel
{
ItemView = ItemViewClone; // <= Doesn't work
ItemView.Item = ItemViewClone.Item; // <= This works
await Callback.InvokeAsync(null);
}
}
If I clone ItemView
it doesn't work. When I edit ItemView.Item.Title
and close the dialog without saving, I see the changes in the parent list.
But if I clone the Item
inside the ItemView
as also shown in the example, it works.
What could I be missing?
Cloning ItemView
to ItemViewClone
do work. It holds all the right values. It's the "resetting" that doesn't work.