首页 > 解决方案 > Google Apps 脚本(网络部署)自动重新加载页面

问题描述

我编写了两个小型 Google Apps,部署为网络应用程序,以“直播”我儿子的棒球比赛。一个应用程序(我称之为“比赛日”)可以让观看比赛的人看到比分、局、球、好球和出局。第二个应用程序(我称之为“Score Keeper”)可以让某人更新这些统计数据。这两个应用程序都可以访问 Google 电子表格。

首次加载时,这两个应用程序都会显示来自 Google 电子表格的正确统计信息,但仅在手动重新加载网页时才会更新统计信息。我想每隔 X 秒自动重新加载“游戏日”,但是当我setTimeout("location.reload(true);", 10000);在我的 Javascript 文件中使用类似的东西时,当页面重新加载时,它是空白的。

我对“Score Keeper”应用程序有同样的问题,因为在单击按钮后——例如增加球的数量——除非我手动重新加载,否则网页上没有任何变化。该按钮确实正确地增加了电子表格中的球数。如果我随后手动重新加载,它会从电子表格中读取统计信息,并再次显示正确的统计信息。

我已经阅读并尝试实现google.script.run.withSuccessHandler(),但是 withSuccessHandler() 的工作原理目前超出了我的理解。如果这确实是这样做的方法,我很乐意为我的特殊情况帮助实施它,因为我无法从其他人的例子中推断出来。

这是我的代码:

“比赛日”代码.gs:

var id = 'Google Spreadsheet ID';
var ss = SpreadsheetApp.openById(id);
var sheet = ss.getSheetByName('score');
var statsRange = sheet.getRange(2,1,1,9);

function doGet(e) {
  var temp = HtmlService.createTemplateFromFile('index');
  temp.stats = getScore();
  return temp.evaluate();
}

function getScore() {
  var s = statsRange.getValues();
  return s[0];
}

function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename).getContent();
}

“比赛日” index.html:

<div class="container">

  <div class="row">
    <div class="col s12 center-align">
      <h5><?= stats[0] + " (home) v. " + stats[1] + " (guest)"; ?></h5>
    </div>
  </div>
  
  <div class="row">
    <div class="col s4 center-align"><b>Home</b></div>
    <div class="col s4 center-align"><b>Inning</b></div>
    <div class="col s4 center-align"><b>Guest</b></div>
  </div>

  <div class="row">
    <div class="col s4 center-align stat"><?= stats[4] ?></div>
    <div class="col s2 right-align stat"><?= stats[2] ?></div>
    <div class="col s2 left-align stat"><?= stats[3] ?></div>
    <div class="col s4 center-align stat"><?= stats[5] ?></div>
  </div>

  <div class="row"></div>

  <div class="row">
    <div class="col s4 center-align"><b>Balls</b></div>
    <div class="col s4 center-align"><b>Strikes</b></div>
    <div class="col s4 center-align"><b>Outs</b></div>
  </div>

  <div class="row">
    <div class="col s4 center-align stat"><?= stats[6] ?></div>
    <div class="col s4 center-align stat"><?= stats[7] ?></div>
    <div class="col s4 center-align stat"><?= stats[8] ?></div>
  </div>

  <div class="row">
    <div class="col s12 center-align refresh">refresh page to update stats</div>
  </div>

</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<?!= include('index-js'); ?>

“比赛日” index-js.html:

<script>
  setTimeout("location.reload(true);", 10000);
</script>

我还尝试在 Google Apps 脚本编辑器中添加一个简单触发器,以便每分钟在 doGet() 函数上运行。它每分钟执行一次触发器,但页面没有改变。

标签: javascripthtmlgoogle-apps-script

解决方案


您可以使用google.script.runhtml 数据属性来实现您的目标:

代码.gs

function getStats() {
  return new Array(15).fill("").map(Math.random)
}

function doGet(e) {
 return HtmlService.createTemplateFromFile('index').evaluate();
}

function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename)
      .getContent();
}

索引.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top" />
    <style>
      .stats::after {
        content: attr(data-stats-value);
      }
    </style>
  </head>

  <body>
    <div class="container">
      <div class="row">
        <div class="col s12 center-align">
          <h5 id="header"></h5>
        </div>
      </div>

      <div class="row">
        <div class="col s4 center-align"><b>Home</b></div>
        <div class="col s4 center-align"><b>Inning</b></div>
        <div class="col s4 center-align"><b>Guest</b></div>
      </div>

      <div class="row">
        <div
          class="col s4 center-align stats"
          data-stats-index="4"
          data-stats-value=""
        ></div>
        <div
          class="col s2 right-align stats"
          data-stats-index="2"
          data-stats-value=""
        ></div>
        <div
          class="col s2 left-align stats"
          data-stats-index="3"
          data-stats-value=""
        ></div>
        <div
          class="col s4 center-align stats"
          data-stats-index="5"
          data-stats-value=""
        ></div>
      </div>

      <div class="row"></div>

      <div class="row">
        <div class="col s4 center-align"><b>Balls</b></div>
        <div class="col s4 center-align"><b>Strikes</b></div>
        <div class="col s4 center-align"><b>Outs</b></div>
      </div>

      <div class="row">
        <div
          class="col s4 center-align stats"
          data-stats-index="6"
          data-stats-value=""
        ></div>
        <div
          class="col s4 center-align stats"
          data-stats-index="7"
          data-stats-value=""
        ></div>
        <div
          class="col s4 center-align stats"
          data-stats-index="8"
          data-stats-value=""
        ></div>
      </div>

      <div class="row">
        <div class="col s12 center-align refresh">
          refresh page to update stats
        </div>
      </div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
    <?!= include('index-js'); ?>
  </body>
</html>

索引-js.html

<script>
  const updateScore = (stats) => {
  document.querySelector('#header').textContent =
    stats[0] + ' (home) v. ' + stats[1] + ' (guest)';
  document
    .querySelectorAll('.stats')
    .forEach(
      (el) => (el.dataset.statsValue = stats[Number(el.dataset.statsIndex)])
    );
};
setInterval(
  () => {google.script.run.withSuccessHandler(updateScore).getStats()},
  10000
);
</script>

推荐阅读