document.getElementById().value не возвращает правильное значение

Я пытаюсь создать поле ввода на планшете робота Pepper, которое позволяет пользователю вводить свой адрес электронной почты голосом. Я использую поле распознавания речи, чтобы получить письмо, которое говорит пользователь, и вызвать событие, чтобы Javascript мог его перехватить и изменить текст. Но кажется, что "document.getElementById("abc").value" никогда не получает то, что в данный момент находится на экране, но значение по умолчанию.

Пример: я говорю «1», он показывает «hello1» (полностью хорошо). Затем я говорю «2», отображается «hello2» (ожидается «hello12»)

Вот мой JS-код:

var session = new QiSession(function(session) {
            // "Connection esterblished!";
          }, function() {
            // "Could not connect to the robot";
          });

// Subscribe to ALMemory Service   
session.service("ALMemory").then(function(ALMemory) {
  // "ALMemory proxy subscription successful!";  
  ALMemory.getData('voice_input').then(function(voice_input){  
        document.getElementById("abc").value += voice_input;        
  });

});

HTML-код:

<input type="text" name="email" id="abc" value="hello">

Есть ли что-то связанное с "сеансом"? Потому что, даже если я использую глобальную переменную для хранения голосового ввода, я могу только изменить значение этой переменной, но не могу получить текущее значение этой переменной внутри функции (то, что я могу получить, это инициализированное значение).


person user10819593    schedule 31.10.2019    source источник


Ответы (2)


К сожалению, мне не удалось найти общедоступную документацию по JavaScript API. Однако это то, что я смог найти.

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

var session = new QiSession(function(session) {
    // "Connection esterblished!";
    // Subscribe to ALMemory Service
    session.service("ALMemory").then(function(ALMemory) {
        // "ALMemory proxy subscription successful!";
        function getVoice() {
            ALMemory.getData('voice_input').then(function(voice_input){
                document.getElementById("abc").value += voice_input;
                getVoice();
            });
        }
        getVoice();
    });
}, function() {
    // "Could not connect to the robot";
});

Во-первых, я переместил подписчика службы в функцию обратного вызова для успешного подключения QiSession, потому что обычно сеанс определяется в вызове асинхронной функции. Когда ALMemory подписан, он определяет и вызывает getVoice, который извлекает речь пользователя, дополняет поле, а затем снова запускает getVoice, чтобы поставить в очередь еще одно прослушивание. Вы можете добавить условие, чтобы остановить его в конце концов. Возможно, также стоит изучить async/await, если Pepper поддерживает это, потому что тогда вы можете легко сделать это с помощью цикла while.

person sploders101    schedule 31.10.2019
comment
Спасибо, я проверил ваш метод, но когда я говорю 1, он говорит hello111111111111..... Ну, вы имеете в виду, что со слушателем что-то не так? Но моя проблема в том, что он слушает (вы можете еще раз взглянуть на мой пример), но document.getElementById(abc).value никогда не получает то, что в данный момент находится на экране. Он получает значение по умолчанию все время (привет в моем случае), даже если буква уже была поймана и отображена на экране (например, привет1). - person user10819593; 04.11.2019
comment
Извините, я, должно быть, неправильно понял вопрос. У меня есть подозрение, что средство визуализации, используемое для веб-страниц, ошибочно считывает значение из атрибута, а не из фактического входного текста. Не могли бы вы попробовать удалить атрибут value из текстового поля в вашем HTML? - person sploders101; 05.11.2019
comment
Да, я удалил атрибут value. Но, к сожалению, проблема сохраняется. - person user10819593; 06.11.2019

Нет ничего плохого в document.getElementById(). Проблема в том, что вы должны реагировать на голосовой ввод, а не только получать текущий голосовой ввод. Это делается путем подписки на событие ALMemory. Вот фрагмент учебника, примерно адаптированный к вашему случаю (но не проверенный):

session.service("ALMemory").then(function (ALMemory) {
  ALMemory.subscriber("voice_input").then(function (subscriber) {
    subscriber.signal.connect(function (state) {
      document.getElementById("abc").value += voice_input;
    });
  });
});

Обратите внимание, что для работы необходимо опубликовать событие для ключа "voice_input", используя ALMemory.raiseEvent.

person Victor Paléologue    schedule 20.11.2019