我正在使用 Google Apps 脚本为 Google 电子表格制作一些自定义 UI。
我正在尝试制作一个抽象的“向导”UI,它有一个任意的面板数组,然后在底部有一个“后退”和“下一步”按钮,根据你所在的“页面”来改变面板的可见性。
我需要某种机制,这样当你从向导的一个页面移动到下一个页面时,我可以在当前“页面”上调用一个函数来说“我现在要离开你了,请保存你的状态”,并且类似于下一个“页面”说“设置好自己,你即将变得可见”(类似于 onShow()、onHide())。
但是,我正在努力从后退和下一个按钮的事件处理程序中找出如何做到这一点。据我所知,访问 UI 元素或将字符串(通过“隐藏”的 ui 元素)传递给事件处理程序非常容易。
这是我目前拥有的相关代码:
/*
*********************************************************************
*/
function createWizard(pages) {
app = UiApp.getActiveApplication();
var currIdx = app.createHidden("currentPanelIndex", 0).setId("CurrentPanelIndex");
var minIdx = app.createHidden("minPanelIndex", 0);
var maxIdx = app.createHidden("maxPanelIndex", pages.length);
app.add(currIdx);
app.add(minIdx);
app.add(maxIdx);
var buttPanel = app.createHorizontalPanel();
var backButton = app.createButton("Back");
var nextButton = app.createButton("Next");
buttPanel.add(backButton).add(nextButton);
var mainPanel = app.createVerticalPanel();
for (var i = 0; i < pages.length; i++) {
pages[i].setId("Panel"+i).setVisible(false);
mainPanel.add(pages[i]);
}
mainPanel.add(buttPanel);
mainPanel.setCellVerticalAlignment(buttPanel, UiApp.VerticalAlignment.BOTTOM);
mainPanel.setCellHorizontalAlignment(buttPanel, UiApp.HorizontalAlignment.RIGHT);
app.add(mainPanel);
// create handler to respond to events
var clickHandler = app.createServerClickHandler("doBack")
.addCallbackElement(currIdx)
.addCallbackElement(minIdx)
.addCallbackElement(maxIdx);
backButton.addClickHandler(clickHandler);
var clickHandler = app.createServerClickHandler("doNext")
.addCallbackElement(currIdx)
.addCallbackElement(minIdx)
.addCallbackElement(maxIdx);
nextButton.addClickHandler(clickHandler);
updateVisibility(currIdx, minIdx, maxIdx)
}
/*
*********************************************************************
*/
function doBack(eventInfo) {
app = UiApp.getActiveApplication();
var parameter = eventInfo.parameter;
var currentPanel = Math.round(Number(parameter.currentPanelIndex));
var minPanel = Math.round(Number(parameter.minPanelIndex));
var maxPanel = Math.round(Number(parameter.maxPanelIndex));
if (currentPanel > minPanel) {
currentPanel--;
// Store the new value
app.getElementById("CurrentPanelIndex").setValue(String(currentPanel));
updateVisibility(currentPanel);
}
return app;
}
/*
*********************************************************************
*/
function doNext(eventInfo) {
app = UiApp.getActiveApplication();
var parameter = eventInfo.parameter;
var currentPanel = parseInt(parameter.currentPanelIndex);
var minPanel = Math.round(Number(parameter.minPanelIndex));
var maxPanel = Math.round(Number(parameter.maxPanelIndex));
Logger.log(currentPanel);
if (currentPanel < maxPanel) {
currentPanel++;
// Store the new value
app.getElementById("CurrentPanelIndex").setValue(String(currentPanel));
updateVisibility(currentPanel, minPanel, maxPanel);
}
return app;
}
/*
*********************************************************************
*/
function updateVisibility(currentPanel, minPanel, maxPanel)
{
for (var i = minPanel; i < maxPanel; i++) {
if (i == currentPanel) {
app.getElementById("Panel"+i).setVisible(true);
// I want to do something like panel[i].onShow()
}
else {
app.getElementById("Panel"+i).setVisible(false);
// I want to do something like panel[i].onShow()
}
}
}
请注意,我认为我不能将 UI 元素扩展为能够具有“onShow”或“onHide”回调。我也看不到如何将回调作为字符串传递!
如有必要,我可以发布更多代码,但如果我以错误的方式处理此问题,我很乐意从头开始,因此我当前的实现细节相对不重要。
免责声明,我非常擅长 C++、C#、Lua 等,但在 JavaScript 方面几乎是新手,所以我可能遗漏了一些非常明显的东西!