Как заставить модальный диалог работать с асинхронным Google Script - PullRequest
0 голосов
/ 24 апреля 2019

Мне нужно запустить массив ролей и открыть модальное диалоговое окно (в HTML) для каждой. У меня была проблема, когда каждое следующее диалоговое окно открывалось до того, как я закрыл предыдущее (из-за асинхронного Google Script.

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

Однако теперь открывается только первое диалоговое окно, и код не проходит через полный цикл for.

function nightStart(nightNumber, playersArray, roleList) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var range = sheet.getRange("Controls!G3:G1000");
  var wakeupOrder = [];
  var sleeping;
  var role;

//collecting the array to define in what order roles wake up
  for (var i = 1; i<=20; i++) {
    var cellValue = range.getCell(i,1).getValue();
    wakeupOrder.push(cellValue);
  }

//the FOR loop that I am trying to make work (open Dialog for each role)
  for (index in wakeupOrder) {
    role = wakeupOrder[index];
    if (roleList.indexOf(role) != -1) {
      sleeping = true;
      roleWakeUp(role, playersArray, roleList);
      do {
        Utilities.sleep(2000);
        //calling global sleeping parameter that is defined as FALSE in the 'nightTargetSelection' function        
        sleeping = PropertiesService.getScriptProperties().getProperty('sleeping'); 
      } while (sleeping != false);
    }
  }   
}



//below is the function that opens the modal dialog (but the server side code still keeps running).
function roleWakeUp (role, playersArray, roleList){    
  //I have removed all code from here for Stack Overflow. The only part that I believe is important is that it opens an HTML dialog with a form
  SpreadsheetApp.getUi().showModalDialog(actionInputDlg, wakeUpText);
}



//Below function is called by the client on HTML form submission. After this form is submitted I need the next dialog to open (i.e need the Utilities.sleep to stop running
function nightTargetSelection (selected, playerNumber){
  var sleeping = false;
  PropertiesService.getScriptProperties().setProperty('sleeping', sleeping);
}

Мне нужен HTML-диалог для открытия каждой «роли» в массиве «wakeupOrder» (если роль существует в «roleList»). Каждый следующий диалог нужно открывать только после отправки предыдущего диалога.

1 Ответ

0 голосов
/ 25 апреля 2019
  • Вы хотите открыть несколько диалогов по порядку.
  • Когда процесс завершен в диалоге, вы хотите открыть следующий диалог.
    • А именно, вы не хотите открывать следующее диалоговое окно до завершения текущего задания.

Если мое понимание верно, как насчет этого ответа?

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

  1. Открыть диалог, запустив start().
  2. При нажатии кнопки «ОК» открывается следующее диалоговое окно с включением следующего задания.
    • Таким образом, каждая работа может быть полностью выполнена.
  3. Когда все задания завершены, запускается done() и диалоговое окно закрывается.

Пример сценария:

Когда вы используете этот скрипт, пожалуйста, скопируйте и вставьте «Code.gs» и «index.html» в «script» и «HTML» в вашем редакторе скриптов соответственно. И, пожалуйста, запустите start(). В этом примере сценария предполагается, что вы используете связанный с контейнером сценарий электронной таблицы.

Code.gs: Google Apps Script

// When all jobs were finished, this function is called.
function done(e) {
  Logger.log(e)
}

// Open a dialog
function openDialog(jobs, i) {
  var template = HtmlService.createTemplateFromFile('index');
  template.jobs = JSON.stringify(jobs);
  template.index = i;
  SpreadsheetApp.getUi().showModalDialog(template.evaluate(), "sample");
}

// Please run this script
function start() {
  var jobs = ["sample1", "sample2", "sample3"];
  openDialog(jobs, 0);
}

index.html: HTML и Javascript

<div id="currentjob"></div>
<input type="button" value="ok" onclick="sample()">
<script>
  var jobs = JSON.parse(<?= jobs ?>);
  var index = Number(<?= index ?>);
  document.getElementById("currentjob").innerHTML= "currentJob: " + jobs[index] + ", index: " + index; 

  function sample() {
    if (index < jobs.length - 1) {
      google.script.run.openDialog(jobs, index + 1); // Modified
    } else {
      google.script.run.withSuccessHandler(()=>google.script.host.close()).done("Done.");
    }
  }
</script>

Ссылки:

Примечание:

  • Это простой пример сценария. Поэтому, пожалуйста, измените это для вашей ситуации.

Если я неправильно понял ваш вопрос, и это был не тот результат, которого вы хотите, я прошу прощения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...