Почему значение двусторонней привязки не работает? Гибридное приложение Maui Blazor

Мне все еще трудно привязаться к простому ярлыку. Проблема кажется простой, но я потратил дни зря, поэтому пришло время обратиться за помощью. Возможно, кто-то знает ответ.

В приведенном ниже коде кнопка работает каждый раз, но нажатие Enter не обновляет страницу, даже если переменная, привязанная к метке, изменилась (я проверил, выведя на консоль с помощью Serilog).

Короче говоря: кнопка и клавиша ввода правильно вызывают одну и ту же функцию, которая каждый раз выполняет задание. К сожалению, страница воспринимает изменение только с помощью кнопки, изменяя статус метки.

Теперь, если я дважды нажму Enter, то, похоже, это сработает, но это не покажет вам, что в фоновом режиме есть исключение, потому что это уже повторяющееся значение. Нажмите Enter в третий раз, и вы получите правильный статус.

Имейте в виду, что я новичок в C#, особенно в гибридных приложениях Maui Blazor.

Спасибо!

HTML:

<div>
<button @onclick=PushToDatabaseFunction> upload to db </button>

 <input @onkeyup = "@(e => KeyPressHandler("inputFieldForUploading", e))"
                @bind-value:event = "oninput"
                @bind-value = "inputFieldString" 
             type = "text" 
             placeholder = "..." /> 
</div>

<div>
          <label>Status Label: @statusLabelBindString</label> 
</div>

В моем коде:

private string statusLabelBindString = ""; 
private string inputFieldString = "";


private async void KeyPressHandler(string inputField, KeyboardEventArgs e) {
    if (e.Key == "Enter")
    {
        if (inputField == "inputFieldForUploading")
            await PushToDatabaseFunction();
        
    }
     }

private async Task PushToDatabaseFunction() {  

//code here takes the inputFieldString and adds it to a database   
//I've triple checked many many times and the code to the db works correctly

await db.insertAsync(inputFieldString);     

 //the following line also works correctly, as the statusLabelBindString  variable >  
// takes on a new value. 

 if (db.status= = "ok")
   statusLabelBindString = $" {inputFieldString} was added to db";
 else
   statusLabelBindString = "Error - Duplicate value";

//Even though statusLabelBindString has a new value (I've checked), the label does not
//update if you press Enter, but from the button it works fine.  



    }

В чем может быть дело?

Спасибо!

Чтобы внести ясность: я пробовал много разных комбинаций. Я также понимаю, что существует функция StateHasChanged(), которая снова отображает экран, но у меня были неоднозначные результаты. Я чувствую, что мне не хватает чего-то довольно основного. Спасибо!

BMET1 24.04.2024 04:31

Вы пытались сделать свой атрибут общедоступным?

Faheem Anis 24.04.2024 04:48

Да, @ФахимАнис! Он просто не работает при вызове через KeyHandlerFunction. Я очень подозреваю, что это проблема времени, когда переменная не обновляется из-за сосредоточения внимания на элементе, но, блин, трудно найти истинную причину.

BMET1 25.04.2024 02:26
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
148
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Прежде всего, я воспроизвел вашу проблему с await Task.Delay(1000);:

private async Task PushToDatabaseFunction() {  
   await Task.Delay(1000);
   statusLabelBindString = $" {inputFieldString} was added to db";
}

Приведенный выше код может воспроизвести вашу проблему. И я могу это исправить двумя способами:

  1. Вызовите StateHasChanged() вручную, чтобы вы также могли попробовать:
if (db.status= = "ok")
{
   statusLabelBindString = $" {inputFieldString} was added to db";
   StateHasChanged();
}
 else{
   statusLabelBindString = "Error - Duplicate value";
   StateHasChanged();
}
  1. Удалите await в await Task.Delay(1000);:
private async Task PushToDatabaseFunction() {  
   Task.Delay(1000);
   statusLabelBindString = $" {inputFieldString} was added to db";
}

Два способа позволяют боту обновить метку при первом нажатии Enter.

  1. Если вы не хотите использовать StateHasChanged(), вы можете просто сделать KeyPressHandler как async Task вместо async void.
private async Task KeyPressHandler(string inputField, KeyboardEventArgs e) 
{
    if (e.Key == "Enter")
    {
        if (inputField == "inputFieldForUploading")
            await PushToDatabaseFunction();
        
    }
}

Когда вы используете async void, пользовательский интерфейс никогда не обновляется (перерисовывается повторно), поскольку StateHasChanged() никогда не вызывается средой выполнения, поскольку среда выполнения не знала, когда асинхронные методы вызвали возврат. Но Task сообщит среде выполнения, когда метод вернется. Поэтому используйте async Task вместо async void.

Большое спасибо @Liyun Zhang - MSFT!!! Я забыл упомянуть одну вещь: метод db.Insert() является асинхронным, поэтому я не могу избавиться от ожидания. Пример кода должен был быть написан как «await db.insertAsync()». Я добавил StateHasChanged(), и он работает, но это все еще сводит меня с ума. Код тот же, но почему он не отображается при вызове из другой функции? Это все равно, что покрасить машину в красный цвет и написать поверх краски «Эта машина красная». Как-то лишнее.

BMET1 27.04.2024 18:55

Пожалуйста, проверьте третий метод в моем обновленном ответе. @BMET1

Liyun Zhang - MSFT 29.04.2024 08:16

ты мужчина! Все предложенные вами решения сработали, но третье мне очень понравилось. Для меня это был полезный опыт. Большое спасибо, что нашли время.

BMET1 01.05.2024 01:32

Другие вопросы по теме