我尝试在应用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
核心部分:
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>
答案 0 :(得分:3)
我认为你误解了一些事情。如果我理解你的问题,你试图调用一些服务器端函数来设置/获取一个值。但实际上你并没有存储这个价值服务器端!你得到的差异是因为不同的背景。
当您使用编辑器时,脚本将在此自己的上下文中执行,这意味着只要脚本执行(只要您保留在页面上),所有实例化的对象/变量都将保留。
但是当你从客户端调用这些函数时,服务器脚本将在调用后执行一次,然后当你“离开”(执行函数的结束)服务器时它的上下文将被销毁。
因此实际上更改了值,但是在执行结束后销毁了更改值的上下文。最后,当您调用get函数时,您将重新创建一个全新的上下文,其中的值使用其默认值进行实例化。
要处理此问题,您必须将变量存储在某个地方,例如。