客户端调用服务器功能设置的服务器端变量是否仍然存在? (没有!)

时间:2014-03-08 20:23:53

标签: javascript html google-apps-script

我尝试在应用javascript中使用Revealing module pattern。我喜欢这个想法,但它似乎最敏锐地揭示的是我对1)javascript 2)应用程序脚本和3)它们如何交互的无知。

在编辑器中运行函数时,该模式运行正常(请参阅下面的test()),但是从实时webapp运行时,它会崩溃。我的印象是服务器端javascript中的值无法使用闭包设置。

每当我在编辑器中运行getEmail或setEmail时,一切正常。如果我从webapp调用它们,setEmail设置的值不会保持设置,因此对getEmail的另一次调用将检索原始值,而不是setEmail设置的值。

如果相同的javascript代码在html页面中作为脚本,我相信设置会坚持下去。 (好吧......必须测试......)。

工作代码: https://script.google.com/macros/s/AKfycbwrmi-b7J5Gqb_SDUUuiO-TTG31hQJVWtMLFvAPTPOb97qZaQw/exec

代码本身:https://script.google.com/d/1LNw54M-hMgafMfsnYBR0QzFlzXDhd9mFX4asghtqejJRC2Uh66zoFuAb/edit?usp=sharing

核心部分:

function doGet() {
  settings.setEmail("start email");
  return HtmlService.createTemplateFromFile('dialog')
            .evaluate()
            .setSandboxMode(HtmlService.SandboxMode.NATIVE)
}

var settings = (function () {
        var email = "blank";
        var getEmail= function () { return email}
        var setEmail= function (m) { email=m}

        return {
          getEmail: getEmail,
          setEmail: setEmail
        }
} ());

function getVal() { return settings.getEmail() }
function setVal(x) { settings.setEmail(x); return "set '" + x + "'"}

function test() {
  Logger.log(setVal("my email"));
  Logger.log(getVal());
}

Html代码:

    <div id="output" >  <?= settings.getEmail()?> </div>
    <br>
    <input  id="input" size="20" type="string" />
    <input type="button" value="Set Value"  onclick="google.script.run.withSuccessHandler(serverSaid).setVal(document.getElementById('input').value);" />
    <input type="button" value="Get Value"  onclick="google.script.run.withSuccessHandler(serverSaid).getVal();" />

    <script>
    function serverSaid(reply) {
          var div = document.getElementById('output');
          var messages= div.innerHTML;
          div.innerHTML = messages +" | " + reply;
    }
    </script>

所以,我尝试在客户端做同样的事情。它按预期工作。这是HTML代码:

<div id="output" >  </div>
<br>
<input  id="input" size="20" type="string" />
<input type="button" value="Set Value"  onclick="serverSaid(setVal(document.getElementById('input').value));" />
<input type="button" value="Get Value"  onclick="serverSaid(getVal());" />

<script>
function serverSaid(reply) {
      var div = document.getElementById('output');
      var messages= div.innerHTML;
      div.innerHTML = messages +" | " + reply;
}

/// everything below has been moved over from server-side 
var settings = (function () {
        var email = "blank";
        var getEmail= function () { return email}
        var setEmail= function (m) { email=m}

        return {
          getEmail: getEmail,
          setEmail: setEmail
        }
} ());

function getVal() { return settings.getEmail() }
function setVal(x) { settings.setEmail(x); return "set '" + x + "'"}

</script>

1 个答案:

答案 0 :(得分:3)

我认为你误解了一些事情。如果我理解你的问题,你试图调用一些服务器端函数来设置/获取一个值。但实际上你并没有存储这个价值服务器端!你得到的差异是因为不同的背景。

当您使用编辑器时,脚本将在此自己的上下文中执行,这意味着只要脚本执行(只要您保留在页面上),所有实例化的对象/变量都将保留。

但是当你从客户端调用这些函数时,服务器脚本将在调用后执行一次,然后当你“离开”(执行函数的结束)服务器时它的上下文将被销毁。

因此实际上更改了值,但是在执行结束后销毁了更改值的上下文。最后,当您调用get函数时,您将重新创建一个全新的上下文,其中的值使用其默认值进行实例化。

要处理此问题,您必须将变量存储在某个地方,例如。