我在我的 google apps 脚本项目中遇到了类逻辑模式问题,我不确定这是我的逻辑、.gs 文件安排,还是这只是 google V8 引擎中的类的意外行为。 尽管如此,我无法弄清楚为什么这段代码无法运行。这是附加到电子表格的谷歌应用程序脚本项目:
(https://docs.google.com/spreadsheets/d/120mXQ5v4XtBeUQGAv57WkXuFhZBGwn6mywEY5vGU_Nw/edit?usp=sharing)
对于上下文,我试图理解依赖注入和耦合。我创建了一个类“TocSheet.gs”来管理目录,当然依赖于 Spreadsheet App 的功能以及 PropertiesService 来存储 TocSheet 实例的状态。任何见解将不胜感激,该链接可供公众使用。要访问代码,请单击扩展 > Apps 脚本。感谢您提供的任何帮助。
本地化问题: 在 TocSheet.gs 文件中,您将看到我正在尝试注入两个 “依赖项”作为参数放入类 TocSheet 构造函数中(电子表格应用程序:new SpreadsheetUtil() 和 propsService:new PropertiesServiceStorage())。由于某种原因,执行日志显示 SpreadsheetUtil 对象已加载到电子表格应用程序变量中,我不确定为什么。
UiManager.gs
class UiUtil {
constructor(spreadsheet) {
this.uI = spreadsheet().getUi();
}
alert(message) {
return this.uI.alert(message);
}
createMenu() {
return this.uI
.createAddonMenu()
.addItem("Insert", "start")
.addSeparator()
.addItem("Remove", "confirmDelete")
.addToUi();
}
confirmDelete() {
const response = this.uI.alert(
"Confirm Deletion",
"Delete this item?",
this.ui.ButtonSet.OK_CANCEL
);
if (response) {
return true;
} else {
this.uI.alert("Deletion Cancelled");
}
return false;
}
}
function start() {
const uI = getSpreadsheetApp().getUi();
const sheet = undefined; //JSON.parse(getPropsService().getScriptProperties().getProperty("sheet"))
//console.log("sheet from props service: ", sheet)
if (!sheet) {
const spreadsheetApp = new SpreadsheetUtility();
const propsService = new PropertiesServiceStorage();
const myToc = new TocSheet(spreadsheetApp, propsService);
uI.alert("sheet created");
console.log(myToc);
}
}
// function setFalse(){
// const doSort = false
// const tocSheet = new SheetManager("TOC", getSpreadsheetApp, getPropsService,getScriptApp);
// }
function confirmDelete() {
const isConfirmed = Ui.confirmDelete;
if (isConfirmed) {
removeToc(isConfirmed);
}
}
电子表格实用程序.gs
class SpreadsheetUtility {
constructor() {
this.activeSheet = SpreadsheetApp.getActive();
}
insertSheet(name) {
return this.activeSheet.insertSheet(name, 0);
}
setNamedRange(name, range) {
this.activeSheet.setNamedRange(name, range);
}
getSheets() {
return this.activeSheet.getSheets();
}
getSheetByName(name) {
return this.activeSheet.getSheetByName(name);
}
}
function myFunction() {
console.log(new SpreadsheetUtility().getSheets());
}
属性服务.gs
class PropertiesServiceStorage {
constructor() {
this.key = "tocSheet";
}
save(tocData) {
const data = JSON.stringify(tocData);
PropertiesService.getScriptProperties().setProperty(this.key, data);
}
load() {
const data = PropertiesService.getScriptProperties().getProperty(
this.key
);
if (!data) {
return null;
}
return JSON.parse(data);
}
}
目录表.gs
class TocSheet {
constructor(name, titles, spreadsheetApp, propsService){
console.log("From Toc: Spreadsheet: ", spreadsheetApp, propsService)
this.state = {};
this.state.name = name || "Table of Contents";
this.spreadsheetApp = spreadsheetApp || new SpreadsheetUtility();
this.propsService = propsService || new PropertiesServiceStorage();
this.state.properties = {
sheetId: null,
titles: null,
range:{
headerName: "TOCHeader",
tocName: "TOC"
}}
this.initialize();
}
static load(){
const storage = new PropertiesServiceStorage();
storage.load();
}
initialize(){
this.createSheet();
this.setSheetId();
this.setTitles();
this.setNamedRanges();
//setTitleLinks();
}
createSheet(){
console.log("name",this.state.name)
const sheet = this.spreadsheetApp.insertSheet("Table of Contents")
this.sheet = sheet;
}
setSheetId(){
this.state.properties.sheetId = this.sheet.getSheetId();
}
setTitles(titles = null){
if(titles){
this.state.properties.titles = titles
}else{
const sheets = this.spreadsheetApp.getSheets();
const titles = sheets.filter(title => title.getSheetId() !== this.sheetId);
this.state.properties.titles = titles;
}
}
setNamedRanges(){
const rangeHeader = this.sheet.getRange(1,1)
const numRows = this.state.properties.titles.length;
const rangeToc = this.sheet.getRange(2,1,numRows)
this.spreadsheetApp.setNamedRange(this.state.properties.range.headerName, rangeHeader)
this.spreadsheetApp.setNamedRange(this.state.properties.range.tocName, rangeToc)
}
}
我真傻,我确定我一定是累了或者什么的。问题是 TocSheet.gs 中的构造函数接受 4 个参数
constructor(name, titles, spreadsheetApp, propsService)
。我通过在 UiManager.gs 文件中创建 TocSheets 实例对象来调用 TocSheets,其中仅传递两个参数:const myToc = new TocSheet(spreadsheetApp, propsService);
。 这种向左移动会导致变量加载不正确,在这种情况下,类 TocSheet.gs 文件中的电子表格应用程序和 propsService 的值未定义。