Google Apps 脚本 - 回调 webapp 中使用的 class 方法
Google Apps Script - Callback for class methods used in webapp
我有一个 GAS,我要在我的网络应用程序中向其提交表格。它执行以下操作:
- 打开一个包含占位符(格式为
##form_field_name##
)的模板文档,对应于表单上的表单域名称
- 复制模板并将其保存到适当的位置
- 遍历提交的值并执行
body.replaceText('##' + key + '##', val);
将值填充到文档中
body.replaceText('##.*##', '');
删除任何留空字段的占位符字符串(因为它们当前未与表单一起提交)
我最终得到一份文档,该文档看起来用户根本没有提交任何数据。我的猜测是,这是因为 #4 在 #3 完成之前 运行ning。有没有办法将#4 指定为回调?类似于:
body.replaceText('##' + key + '##', val, () => {
body.replaceText('##.*##', '');
});
这是执行 replaceText()
ing 的函数的代码:
/**
* Iterate through obj of keys/values and replace ##key##
* with value in doc
**/
function doFindAndReplace(obj, doc) {
try {
//body = doc.getBody();
var id = doc.getId();
var _doc = DocumentApp.openById(id);
var body = _doc.getBody();
//var doc = _doc;
//Logger.log(body);
for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
var val = obj[prop];
var key = prop.indexOf('intake') === 0 ? prop.toUpperCase() : '';
//Logger.log(key + ' = ' + val);
//Logger.log(typeof val);
body.replaceText('##' + key + '##', val);
_doc.saveAndClose();
var _doc2 = DocumentApp.openById(id);
body = _doc2.getBody();
body.replaceText('##.*##', '');
}
}
} catch(e) {
Logger.log('doFindAndReplace() | ' + e);
errors.push({
fxn: 'doFindAndReplace',
msg: e,
custom: 'id=' + id
});
return false;
}
return doc;
}
参数 obj
是一个包含提交的表单数据的对象,doc
是对新创建的文档的引用,在该文档中进行查找和替换。
如果没有那样的可能,我正在考虑添加一个 运行 #4 (body.replaceText('##.*##', '');
) 的 onOpen
触发器。这将要求用户在在线时首次打开文档,并且大部分用例是离线使用新创建的文档。
任何人都可以提出另一种解决方法吗?
** **编辑** **
我将我的代码(如上所示)更新为 `saveAndClose()`,然后在 运行 执行第二个 `replaceText()` 之前重新打开。我收到以下错误:
Document is closed, its contents cannot be updated
我知道,您会认为它会在 saveAndClose()
之后出现。但是错误指向的那一行,即使我删除了它之后的其余行,也会发生同样的错误。
如果我按原样删除带有代码的 saveAndClose()
行,我又会遇到原来的问题。
我认为这与
不是同一个问题
** **编辑 2** **
这是传递给函数的对象的示例:
{
intake_activity_level: "Normal",
intake_assessment_comments: "",
intake_client_addr: "1600 Fake St XXXX, XX 12345",
intake_client_email: "xxx@gmail.com",
intake_client_name: "Dan Tester",
intake_client_phone: "(917) 555-1212",
intake_consent: "yes",
intake_consent_owner: "Jim David",
intake_food_intake: "Decreased",
intake_gen_food: "",
intake_gen_health: "sit dolam amet",
intake_gen_meds: "re et sapien et, consectetur rhoncus lacus. Aliqua Vivamus ipsum diam, venenatis a turpis eget, volu",
intake_gen_reasons: "Lorem ipsum",
intake_gen_vaccine: "Yes",
intake_misc_comments: "",
intake_misc_descriptor: "wood",
intake_panting: "Increased",
intake_pet_breed: "Pug",
intake_pet_dob: "8/11/2015",
intake_pet_name: "FLuffy",
intake_pet_sex: "Spayed Female",
intake_pet_species: "Dog",
intake_pet_weight: "140lbs",
intake_sleep: "Increased",
intake_source: "Sally Balls",
intake_stiffness: "Normal",
intake_symptoms: "coughing, belching or gas",
intake_vet: "Urban Vet",
intake_voice: "Increased",
intake_water_intake: "Decreased"
}
并且可以访问文档的简化版本 here。
- 您想使用
obj
将 '##' + key + '##'
替换为 va;
和 body.replaceText('##' + key + '##', val);
。
- 您想将
##.*##
替换为 ''
为 body.replaceText('##.*##', '');
。
- 你想要 运行
body.replaceText('##.*##', '');
毕竟 body.replaceText('##' + key + '##', val);
是 运行.
如果我的理解是正确的,这个答案怎么样?
在您当前的脚本中,body.replaceText('##.*##', '');
被放入 for 循环中。这样,只使用 intake_activity_level: "Normal",
,不使用其他对象。在这种情况下,在第一个 body.replaceText('##' + key + '##', val);
是 运行 之后,所有 ##key##
值都被 body.replaceText('##.*##', '');
删除。我认为这可能是您遇到问题的原因。
修改后的脚本:
当您的脚本修改时,请修改如下。
从:
for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
var val = obj[prop];
var key = prop.indexOf('intake') === 0 ? prop.toUpperCase() : '';
//Logger.log(key + ' = ' + val);
//Logger.log(typeof val);
body.replaceText('##' + key + '##', val);
_doc.saveAndClose();
var _doc2 = DocumentApp.openById(id);
body = _doc2.getBody();
body.replaceText('##.*##', '');
}
}
到:
for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
var val = obj[prop];
var key = prop.indexOf('intake') === 0 ? prop.toUpperCase() : '';
body.replaceText('##' + key + '##', val);
}
}
body.replaceText('##.*##', '');
- 在这个修改中,首先,
body.replaceText('##' + key + '##', val);
在for循环中是运行。然后,body.replaceText('##.*##', '');
是 for 循环外的 运行。
注:
- 如果需要
saveAndClose()
,在body.replaceText('##.*##', '');
之后加上doc.saveAndClose()
怎么样?
我有一个 GAS,我要在我的网络应用程序中向其提交表格。它执行以下操作:
- 打开一个包含占位符(格式为
##form_field_name##
)的模板文档,对应于表单上的表单域名称 - 复制模板并将其保存到适当的位置
- 遍历提交的值并执行
body.replaceText('##' + key + '##', val);
将值填充到文档中 body.replaceText('##.*##', '');
删除任何留空字段的占位符字符串(因为它们当前未与表单一起提交)
我最终得到一份文档,该文档看起来用户根本没有提交任何数据。我的猜测是,这是因为 #4 在 #3 完成之前 运行ning。有没有办法将#4 指定为回调?类似于:
body.replaceText('##' + key + '##', val, () => {
body.replaceText('##.*##', '');
});
这是执行 replaceText()
ing 的函数的代码:
/**
* Iterate through obj of keys/values and replace ##key##
* with value in doc
**/
function doFindAndReplace(obj, doc) {
try {
//body = doc.getBody();
var id = doc.getId();
var _doc = DocumentApp.openById(id);
var body = _doc.getBody();
//var doc = _doc;
//Logger.log(body);
for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
var val = obj[prop];
var key = prop.indexOf('intake') === 0 ? prop.toUpperCase() : '';
//Logger.log(key + ' = ' + val);
//Logger.log(typeof val);
body.replaceText('##' + key + '##', val);
_doc.saveAndClose();
var _doc2 = DocumentApp.openById(id);
body = _doc2.getBody();
body.replaceText('##.*##', '');
}
}
} catch(e) {
Logger.log('doFindAndReplace() | ' + e);
errors.push({
fxn: 'doFindAndReplace',
msg: e,
custom: 'id=' + id
});
return false;
}
return doc;
}
参数 obj
是一个包含提交的表单数据的对象,doc
是对新创建的文档的引用,在该文档中进行查找和替换。
如果没有那样的可能,我正在考虑添加一个 运行 #4 (body.replaceText('##.*##', '');
) 的 onOpen
触发器。这将要求用户在在线时首次打开文档,并且大部分用例是离线使用新创建的文档。
任何人都可以提出另一种解决方法吗?
** **编辑** **
我将我的代码(如上所示)更新为 `saveAndClose()`,然后在 运行 执行第二个 `replaceText()` 之前重新打开。我收到以下错误:
Document is closed, its contents cannot be updated
我知道,您会认为它会在 saveAndClose()
之后出现。但是错误指向的那一行,即使我删除了它之后的其余行,也会发生同样的错误。
如果我按原样删除带有代码的 saveAndClose()
行,我又会遇到原来的问题。
我认为这与
** **编辑 2** **
这是传递给函数的对象的示例:
{
intake_activity_level: "Normal",
intake_assessment_comments: "",
intake_client_addr: "1600 Fake St XXXX, XX 12345",
intake_client_email: "xxx@gmail.com",
intake_client_name: "Dan Tester",
intake_client_phone: "(917) 555-1212",
intake_consent: "yes",
intake_consent_owner: "Jim David",
intake_food_intake: "Decreased",
intake_gen_food: "",
intake_gen_health: "sit dolam amet",
intake_gen_meds: "re et sapien et, consectetur rhoncus lacus. Aliqua Vivamus ipsum diam, venenatis a turpis eget, volu",
intake_gen_reasons: "Lorem ipsum",
intake_gen_vaccine: "Yes",
intake_misc_comments: "",
intake_misc_descriptor: "wood",
intake_panting: "Increased",
intake_pet_breed: "Pug",
intake_pet_dob: "8/11/2015",
intake_pet_name: "FLuffy",
intake_pet_sex: "Spayed Female",
intake_pet_species: "Dog",
intake_pet_weight: "140lbs",
intake_sleep: "Increased",
intake_source: "Sally Balls",
intake_stiffness: "Normal",
intake_symptoms: "coughing, belching or gas",
intake_vet: "Urban Vet",
intake_voice: "Increased",
intake_water_intake: "Decreased"
}
并且可以访问文档的简化版本 here。
- 您想使用
obj
将'##' + key + '##'
替换为va;
和body.replaceText('##' + key + '##', val);
。 - 您想将
##.*##
替换为''
为body.replaceText('##.*##', '');
。 - 你想要 运行
body.replaceText('##.*##', '');
毕竟body.replaceText('##' + key + '##', val);
是 运行.
如果我的理解是正确的,这个答案怎么样?
在您当前的脚本中,body.replaceText('##.*##', '');
被放入 for 循环中。这样,只使用 intake_activity_level: "Normal",
,不使用其他对象。在这种情况下,在第一个 body.replaceText('##' + key + '##', val);
是 运行 之后,所有 ##key##
值都被 body.replaceText('##.*##', '');
删除。我认为这可能是您遇到问题的原因。
修改后的脚本:
当您的脚本修改时,请修改如下。
从:for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
var val = obj[prop];
var key = prop.indexOf('intake') === 0 ? prop.toUpperCase() : '';
//Logger.log(key + ' = ' + val);
//Logger.log(typeof val);
body.replaceText('##' + key + '##', val);
_doc.saveAndClose();
var _doc2 = DocumentApp.openById(id);
body = _doc2.getBody();
body.replaceText('##.*##', '');
}
}
到:
for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
var val = obj[prop];
var key = prop.indexOf('intake') === 0 ? prop.toUpperCase() : '';
body.replaceText('##' + key + '##', val);
}
}
body.replaceText('##.*##', '');
- 在这个修改中,首先,
body.replaceText('##' + key + '##', val);
在for循环中是运行。然后,body.replaceText('##.*##', '');
是 for 循环外的 运行。
注:
- 如果需要
saveAndClose()
,在body.replaceText('##.*##', '');
之后加上doc.saveAndClose()
怎么样?