在另一个例程中触发UiApp-builder回调

时间:2014-04-12 10:29:56

标签: google-apps-script

Serge's solution here似乎是解决这个问题的方法,但我有点害怕我的情况可能会有所不同...

我有一个按钮,用户可以在其中向FlexTable添加一组带控件的新行,以便允许他们将新成员插入到记录集中。在设计和构建应用程序之后(尽管有相反的保证),然后添加了一个要求,以便用户能够在以后编辑记录集。

我终于设法检索并正确显示在Ui上的数据 - 用于单个成员记录集。作为最后阶段,我现在试图扩展它以适应具有多个成员的记录集。显然,这需要确定记录集中有多少成员,然后将新行/控制组添加到FlexTable,然后将成员加载到每个控制组中。

因此,在此例程中,(取决于有多少成员)我可能需要触发相同的回调,用户通常使用按钮进行回调。然而,与Serge的优秀示例的不同之处在于,一旦所有Ui组件都到位,他的代码会在例程结束时触发复选框回调。我的情况需要动态执行 - 到目前为止,我收到'意外错误',这表明在我的代码尝试为其分配值之前,Ui无法使用添加的FlexTable控件进行更新。 / p>

有没有人对此问题有任何见解?我唯一可以完全重建一个固定的Ui并省去动态行集模型吗?

代码如下 -

1。添加控件的事件:

var app = UiApp.getActiveApplication();
var oFlexGrid = app.getElementById('ExpenseDetail');
var oRowCount = app.getElementById('rowCount');
var oScriptDBId = app.getElementById('scriptDBId');
var iRows = parseInt(e.parameter.rowCount);      
var sVId = e.parameter.scriptDBId;

var vGridDefs = loadArrayById(sVId); //retrieve upload definition array from ScriptDB
var vControlNames = [];

if (isOdd(iRows)){
  var sColour = 'AliceBlue';
} else {
  var sColour = 'LavenderBlush';           
};

oFlexGrid.insertRow(0);
oFlexGrid.insertRow(0);
oFlexGrid.insertRow(0);
oFlexGrid.insertRow(0);

oFlexGrid.setRowStyleAttributes(0,{'backgroundColor':sColour});
oFlexGrid.setRowStyleAttributes(1,{'backgroundColor':sColour});
oFlexGrid.setRowStyleAttributes(2,{'backgroundColor':sColour});
oFlexGrid.setRowStyleAttributes(3,{'backgroundColor':sColour});   

var vExpenseDef = Get_NamedRangeValues_(CONST_SSKEY_APP,'UIAPP_GridExpense');
iRows = iRows+1;   

vControlNames = CreateGrid_MixedSet_(iRows, vExpenseDef, oFlexGrid, app);  
oRowCount.setText(iRows.toString()).setValue(iRows.toString());       

//SOME INCONSEQUENTIAL CODE REMOVED HERE, LET ME KNOW IF YOU NEED IT

vGridDefs = vGridDefs.concat(vControlNames); // unify grid definition arrays     
var sAryId = saveArray('expenseFieldDef', vGridDefs);
oScriptDBId.setText(sAryId).setValue(sAryId); //store array and save ScriptDB ID        

if (e.parameter.source == 'btnExpenseAdd'){
  hideDialog(); //IGNORE CHEKCBOX-DRIVEN CALLS
};

return app;

2。调用事件的例程

var app = UiApp.getActiveApplication();
var oPanelExpense = app.getElementById('mainPanelExpense');
var oPanelIncome = app.getElementById('mainPanelIncome');
var oPanelEdit = app.getElementById('mainPanelEdit');    

var chkExpenseAdd= app.getElementById('chkExpenseAdd');    
var bExpenseTrigger = e.parameter.chkExpenseAdd;

var sVoucherId = nnGenericFuncLib.cacheLoadObject(CACHE_EDIT_VOUCHERID);
var sVoucher = e.parameter.ListSearch1Vouchers;    

var aryVoucherInfo = getVoucherEditDetail(sVoucherId);     
//SAVE FOR RECORD MARKING CALLBACK
nnGenericFuncLib.cacheSaveObject(CACHE_EDIT_OLDRECORDS, JSON.stringify(aryVoucherInfo), CACHE_TIMEOUT);

sVoucher = nnGenericFuncLib.textPad(sVoucher, '0', 7);    
var bExp = (sVoucher.substring(0,2) == '03')

var oRowCount = app.getElementById('rowCount');
var iRowCount = parseInt(e.parameter.rowCount);

var sControlName = '';
var vControlVal = '';
var iExpIdx = 0;
var sControlType = '';
var oControl = '';
var vSummaryTotal = 0;

for (var iVal in aryVoucherInfo){    
  sControlName = aryVoucherInfo[iVal][2];
  vControlVal = aryVoucherInfo[iVal][3];

  switch (sControlName){
    case 'ESUM60': 
      vSummaryTotal = vControlVal;
      break;
    case 'EXUSRN': 
      continue; //DON'T OVERWRITE CURRENT USERNAME
      break;
  };            

  if (sControlName.indexOf('_')!=-1){ //TEST FOR CONTROL SET MEMBER      
    var aryControlSet = sControlName.split('_');

    if (parseInt(aryControlSet[1])>iRowCount){//*** TRIGGER THE EVENT ***          
      Logger.log(bExpenseTrigger + ' - ' + !bExpenseTrigger);
      chkExpenseAdd.setValue(!bExpenseTrigger, true);
      iRowCount = iRowCount +1;
    };

  };

  oControl = app.getElementById(sControlName);      
  var vCache = cacheSaveReturn(CACHE_UIEX_LISTS,sControlName);

  if (typeof vCache == 'undefined'){       

    oControl.setValue(vControlVal);
    oControl.setText(vControlVal);   
    //controlSetTextBox(oControl,vControlVal);
    //controlSetDateBox(oControl,vControlVal);  
  } else {

    if (!(nnGenericFuncLib.arrayIsReal(vCache))){
      vCache = JSON.parse(vCache); 
    };

    vCache = vCache.indexOf(vControlVal);        

    if (vCache != -1){
      oControl.setSelectedIndex(vCache);
    } else {
      controlSetListBox(oControl,vControlVal);
    };
  };

};

//SOME CODE REMOVED HERE

hideDialog();    
return app;

1 个答案:

答案 0 :(得分:0)

Mogsdad to the rescue!

对于那些在课堂后面(和我一起)的人的答案(见上文)是简单地将app实例参数(e)传递给事件函数,直接从主例程调用它,从而保持时间顺序当它返回应用程序以完成例程时的步骤。在这种情况下无需使用复选框。

这只花了我一整天,但感谢Mogsdad! :)

下面的片段取自OP中的1/2路向下代码示例2:

  if (sControlName.indexOf('_')!=-1){ //TEST FOR CONTROL SET MEMBER      
    var aryControlSet = sControlName.split('_');

    if (parseInt(aryControlSet[1])>iRowCount){      
      eventAddExpense(e); //THAT'S ALL IT TAKES
      iRowCount = iRowCount +1;
    };

  };