Serge's solution here似乎是解决这个问题的方法,但我有点害怕我的情况可能会有所不同...
我有一个按钮,用户可以在其中向FlexTable添加一组带控件的新行,以便允许他们将新成员插入到记录集中。在设计和构建应用程序之后(尽管有相反的保证),然后添加了一个要求,以便用户能够在以后编辑记录集。
我终于设法检索并正确显示在Ui上的数据 - 用于单个成员记录集。作为最后阶段,我现在试图扩展它以适应具有多个成员的记录集。显然,这需要确定记录集中有多少成员,然后将新行/控制组添加到FlexTable,然后将成员加载到每个控制组中。
因此,在此例程中,(取决于有多少成员)我可能需要触发相同的回调,用户通常使用按钮进行回调。然而,与Serge的优秀示例的不同之处在于,一旦所有Ui组件都到位,他的代码会在例程结束时触发复选框回调。我的情况需要动态执行 - 到目前为止,我收到'意外错误',这表明在我的代码尝试为其分配值之前,Ui无法使用添加的FlexTable控件进行更新。 / p>
有没有人对此问题有任何见解?我唯一可以完全重建一个固定的Ui并省去动态行集模型吗?
代码如下 -
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;
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;
答案 0 :(得分:0)
对于那些在课堂后面(和我一起)的人的答案(见上文)是简单地将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;
};
};