Welcome to JiKe DevOps Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
358 views
in Technique[技术] by (71.8m points)

asp.net core - Property values of the same type are updated incorrectly in Blazor

Background:

I wanted to achieve the following:

  1. Keep a copy of the data context and use the copy for editing
  2. So that I can reset the data context back to its unchanged state using an onclick event by doing copyValue = unchangedValue

Here is my attempt (it's been trimmed down in size to reduce noises but it has the same issue):

**index.razor**

@page "/"
@using SolutionName.Data
@using System.Reflection

<EditForm Model="Items2">
    <table class="table">
        <thead>
            <tr>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var i in Items2)
            {
                <tr @key="@i.GetHashCode()">
                    <InputText @bind-Value="i.Summary"></InputText>
                </tr>
            }
        </tbody>
    </table>
</EditForm>



//
//reflections for debuggings
//
@if (Items != null)
{
    <p>
        @foreach (var item in Items)
        {
            <span>@($"Items.{typeof(WeatherForecast).GetProperty(nameof(WeatherForecast.Summary)).Name}={typeof(WeatherForecast).GetProperty(nameof(WeatherForecast.Summary)).GetValue(item)}")</span>
        }
    </p>
}
@if (Items2 != null)
{
    <p>
        @foreach (var item in Items2)
        {
            <span>@($"Items2.{typeof(WeatherForecast).GetProperty(nameof(WeatherForecast.Summary)).Name}={typeof(WeatherForecast).GetProperty(nameof(WeatherForecast.Summary)).GetValue(item)}")</span>
        }
    </p>
}


@code{
    List<WeatherForecast> Items = new List<WeatherForecast>();

    List<WeatherForecast> Items2 = new List<WeatherForecast>();
    protected override void OnInitialized()
    {
        Items = new List<WeatherForecast>()
        {
            new WeatherForecast()
            {
                Date = DateTime.Now,
                Summary = "123",
                TemperatureC = 1
            }
        };
        Items2 = Items;
    }
    private void ResetItems2()
    {
        Items2 = Items;
    }
}

As you can see, I am binding Items2, and not Items, to the <EditForm>. However, updating the summary seems to update both Items2 and Items. I also noticed that this will not happen if Items and Items2 are of two different types (say that they have exactly the same properties, and I cast one to another...)

Two questions:

Why is Item updated in this case?

Is there a way to only update Items2 and not Items, while allowing Items and Items2 to be the same type?

Detailed steps to reproduce the issue:

Step 1. Initialized and render for the first time

enter image description here

Step 2. Change the value to 456 and then tab away

enter image description here

The expected result should be

Items.Summary=123 (not 456)

Items2.Summary=456


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

Please log in or register to answer this question.

1 Answer

0 votes
by (71.8m points)

The issue is that you're using reference type assignment. When you assign Items to Items2, you actually assign a pointer to Itemss values. Both variable point to the same list of objects.

If it's applicable create a value type instead. Saving data in the local storage and then retrieving it is a viable solution.

This:

List<WeatherForecast> Items = new List<WeatherForecast>();

List<WeatherForecast> Items2 = new List<WeatherForecast>();

is superfluous. Code like this:

List<WeatherForecast> Items;

List<WeatherForecast> Items2;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to JiKe DevOps Community for programmer and developer-Open, Learning and Share
...