Значения свойств одного и того же типа неверно обновляются в Blazor

#asp.net-core #components #blazor

#asp.net-core #Компоненты #blazor

Вопрос:

Фон:

Я хотел добиться следующего:

  1. Сохраните копию контекста данных и используйте копию для редактирования
  2. Чтобы я мог сбросить контекст данных обратно в его неизменное состояние, используя событие onclick, выполнив copyValue = unchangedValue

Вот моя попытка (она была уменьшена по размеру, чтобы уменьшить шумы, но имеет ту же проблему):

 **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;
    }
}

 

Как вы можете видеть, я привязан Items2 , а не Items к <EditForm> .
Однако обновление сводки, по-видимому, обновляет и Items2 то, и Items другое. Я также заметил, что этого не произойдет, если Items и Items2 имеют два разных типа (скажем, что они имеют точно такие же свойства, и я применяю одно к другому …)

Два вопроса:

Почему Item обновляется в этом случае?

Есть ли способ только обновлять Items2 , а не Items нет, при этом позволяя Items и Items2 быть одного типа?

Подробные шаги по воспроизведению проблемы:

Шаг 1. Инициализируется и отображается в первый раз

введите описание изображения здесь

Шаг 2. Измените значение на 456, а затем уберите табуляцию

введите описание изображения здесь

Ожидаемый результат должен быть

Товары.Сводка = 123 (не 456)

Items2.Summary=456

Ответ №1:

Проблема в том, что вы используете назначение ссылочного типа. Когда вы присваиваете Items значение Items2 , вы фактически присваиваете указатель Items s значениям. Обе переменные указывают на один и тот же список объектов.

Если это применимо, создайте вместо этого тип значения. Сохранение данных в локальном хранилище и последующее их извлечение является жизнеспособным решением.

Это:

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

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

является излишним. Код, подобный этому:

 List<WeatherForecast> Items;

List<WeatherForecast> Items2;
 

Комментарии:

1. Привет и спасибо за подсказку. Я погуглил «Назначение ссылочного типа», и кажется, что мой подход не копирует данные, а просто создает адрес, который указывает на источник. Это означает, что если я изменю одно из них, оба будут изменены, поскольку они указывают на одно и то же местоположение.