Bound свойство не обновляется при изменении

голоса
1

В моем приложении Blazor, у меня есть следующие поля ввода в представлении:

<input bind=@amount.Display type=text />

Это связанно со свойством, определенным с помощью следующих аксессоров:

get
{
    return _display;
}
set
{
    var parsed = Decimal.Parse(value);
    _display = parsed.ToString(F2);
}

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

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

Задан 20/10/2018 в 05:41
источник пользователем
На других языках...                            


3 ответов

голоса
0

Основная проблема заключается в том , что Blazor просто не собирается обновить текстовое поле , если он думает , что его значение не изменилось. Часть этой проблемы с вашим примером является то , что внутреннее представление значения (вашей собственности) иногда не вяжется с тем, что вы видите в текстовом поле ( 2против 2.00). Но насколько Blazor обеспокоен , если значение свойства не изменится , это не будет распространяться связывание обратно в текстовое поле.

Я играл с несколькими вариантами кода (вручную «связывания» с использованием valueи onchange) , но в конечном счете , если к тому времени ваш код завершает обновление свойство значения и значение такое же , как это было раньше, ничего не произойдет.

Единственный способ решения проблемы я могу думать о том , чтобы ввести действительно уродливые взломать с помощью асинхр. Когда вы сделаете это, цикл обработки событий завершается после того , как await(blazor примет новое значение 2), и blazor снова проверьте , чтобы увидеть , если что - то изменилось , когда он возобновляет awaitвызов , так как на тот момент это новый виток цикла событий. Поскольку новое значение теперь будет 2.00вместо 2него обновляет текстовое поле.

@functions {
    private string value;

    private string Value
    {
        get => value;
        set => SetValue(value);
    }

    private async void SetValue(string value)
    {
        this.value = value;
        await Task.Delay(1);
        this.value = decimal.Parse(value).ToString("F2");
        StateHasChanged();
    }
}

Надеюсь , кто - то , кто знает больше о Blazor , чем я могу предложить что - то менее отвратительный. Но это действительно работает. (кстати, Task.Delay(0)это не работает, по- видимому из - за некоторую оптимизацию , где задача уже завершена , и поэтому не завербовать обещание выйти из цикла событий.)

Примечание:
После того, как формат строка Blazor (т.е. format-value="yyyy-MM-dd") принимает номера, вы, вероятно, смогут упростить это, просто хранить значение в виде десятичной дроби и используя строку формата в бритвенной разметке непосредственно.

Ответил 21/10/2018 в 17:07
источник пользователем

голоса
0

Я считаю, что ваш вопрос не имеет ничего общего с Blazor, и все, что с вашим браузером.

«1,00» => «2» заканчивается «2,00». потому что стоимость вашего текстового поля изменилось, и, таким образом, ваш браузер поднять событие изменения.

«2,00» => «2» остается «2», так как значение вашего текстового поля не изменилось, и, таким образом, ваш браузер не вызывает событие изменения.

Примечание: метод StateHasChanged автоматически вызывается после события. Привязки механизм ввода элемента на основе события изменения ... опять же, нет необходимости вызывать метод StateHasChanged.

Ответил 20/10/2018 в 09:29
источник пользователем

голоса
0

Если вы хотите, чтобы заставить интерфейс повторной визуализации, в Blazor 0,6 Я рекомендую использовать StateHasChanged()

get
{
    return _display;
}
set
{
    var parsed = Decimal.Parse(value);
    _display = parsed.ToString("F2");
    StateHasChanged();
}

Реальная причина , почему Blazor повторно не рендер: это попытаться сохранить восстановление HTML. Поскольку Blazor знает , что вы обязаны свойство inputэто верить , что нет необходимости , чтобы вызвать повторную визуализацию после установки свойства.

Работа обновления:

  1. Пользователь введите текст «5» и нажмите Tab
  2. Html onchangeсобытие генерируется
  3. Blazor захватить onchangeдаже и вызовamount.Display = "5";
  4. Готово.
Ответил 20/10/2018 в 07:01
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more