【问题标题】:Passing event objects from trigger function to another function将事件对象从触发函数传递到另一个函数
【发布时间】:2019-06-10 23:32:05
【问题描述】:

我决定将这个onEdit(e) 触发器函数分解为多个函数,但是当我这样做时,事件对象(e) 部分“丢失了”。搞砸了一段时间后,我终于让它再次工作,但我认为这不是最有效的解决方案。

有什么建议吗,或者这是否足够好?基本上,我只是添加了var e = e; 并让它再次工作。

function onEdit(e){
  Logger.log(e);
  
  if(e.range.getSheet().getName() == 'Estimate'){   
    var e = e;
    Logger.log("Starting subCatDV...");
    subCatDV(e);
    Logger.log("Finished subCatDV!");

    
    Logger.log("Starting itemDV...");
    itemDV(e);
    Logger.log("Finished itemDV!");


    Logger.log("Starting subItemDV...");
    subItemDV(e);
    Logger.log("Finished subItemDV!");
    
  }    
  
  if(e.range.getSheet().getName() == 'Items'){
    subCatDV();
  }
  
  return;
    
}  

这是似乎没有收到event objects的函数

function subItemDV(e){
  // Populate sub-item data validations
  
  var estss = SpreadsheetApp.getActive().getSheetByName('Estimate');
  var itemss = SpreadsheetApp.getActive().getSheetByName('Items');
  var subItemDVss = SpreadsheetApp.getActive().getSheetByName('subItemDataValidations');
  var activeCell = estss.getActiveCell();
  
  Logger.log("I'm in subItemDV...");
  Logger.log(e);
  Logger.log(activeCell);
  
  Logger.log("Checking sheet name...");
  
  if(activeCell.getColumn() == 3 && activeCell.getRow() > 1){
    if(e.range.getSheet().getName() == 'Items') return;
    
    Logger.log("Not in 'Items' sheet!  Moving on...");
    
    activeCell.offset(0, 1).clearContent().clearDataValidations();
    
    var subItem = subItemDVss.getRange(activeCell.getRow(),activeCell.getColumn(),itemss.getLastColumn()).getValues();
    var subItemIndex = subItem[0].indexOf(activeCell.getValue()) + 2;
    
    
    Logger.log("Checking subItemIndex...");
    
    if(subItemIndex != 0){
      
      var subItemValidationRange = subItemDVss.getRange(activeCell.getRow(),4,1,subItemDVss.getLastColumn());
      var subItemValidationRule = SpreadsheetApp.newDataValidation().requireValueInRange(subItemValidationRange).build();
      
      activeCell.offset(0, 1).setDataValidation(subItemValidationRule);

      Logger.log("Finished checking subItemIndex...");
      
    }
  }
}  

【问题讨论】:

  • 请澄清在什么通话期间以及在什么情况下event object 会丢失?它被构造为only in response 以触发(在您的情况下为“onEdit”),并且如果您不重新分配或修改它,它将在整个回调链中持续存在。顺便说一句,由于您的两个 if 语句检查的是同一件事,因此您应该改用一个 if..else 语句
  • 你好@OlegValter!谢谢您的答复!我编辑了 OP 以反映受影响的功能。
  • 嗨,特雷!感谢您的澄清!你能告诉你遇到了什么问题吗?从您当前的代码来看,没有什么可以导致event object 变为undefined(顺便说一句,这就是您所说的“丢失”吗?)
  • 是的,我想这就是我的意思。我只是在 GAS 中摸索,试图自学。所以我并不总是使用适当的术语。在我添加var e = e; 并将(e) 添加到每个函数之前,它只是没有传递值并停止中间函数。因此,所有的Logger 都散布在各处。试图查明它停止的位置

标签: events google-apps-script google-sheets triggers


【解决方案1】:

为了不夸大 cmets 中的讨论:您可以安全地删除脚本中的 var e = e 分配,因为它不会影响您的脚本更新版本解决的问题:

  1. e 是一个事件对象,它被构造为对触发触发器的响应。由于在您的情况下触发器是onEdit(e) 触发器,因此事件对象是undefined,直到在目标电子表格中进行编辑(请注意,脚本触发编辑不计入);
  2. 即使您使用参数调用函数(如doSomething(e)),以防您不通过arguments 对象访问参数,或者在函数声明function doSomething(e) 中明确定义它,事件对象不会被持久化;

另外,您可能错过了最后一个 subCatDV() 调用中的 e 绑定 + 可以优化 if 语句(顺便说一句,不要使用 equality comparison,而是使用 identity 比较,它将为您节省以后的调试时间):

var name = e.range.getSheet().getName();
if(name === 'Estimate') {
  doSomething(e);
}else if(name === 'Items') { //identity comparison ensures type match;
  doSomethingElse(e);
}

有用的链接

  1. 事件对象reference;

  2. arguments对象reference;

【讨论】:

  • 请不要对字符串文字使用 ===
  • 你的意思是字符串对象吗?因为'foo'==='foo' 通过了严格的相等测试,var f = 'foo'; f==='foo'var f = 'foo'; var ff = 'foo'; f===ff 甚至模板字面量也是如此。
猜你喜欢
  • 1970-01-01
  • 2013-03-15
  • 1970-01-01
  • 1970-01-01
  • 2014-04-27
  • 2018-07-19
  • 2015-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多