为什么我的下拉列表在从谷歌表单更新webapp中的第二个依赖下拉列表时如此缓慢



我在第一选择中有大约50个数据,在第二选择中有一些。这是我的完整代码。我的问题尤其是第一选择选项中的第一项选择。当选择第一项时,更新第二选择选项的速度慢得令人恼火。

gs代码:

function get1st() {
var ss = getSS();
var sheet = ss.getSheetByName('data'); 
var range  = sheet.getRange("A2:A");//or "A2:A" for all data
var vA  = range.getValues();
var dataSize = vA.length;
var options = [];
Logger.log("array size="+ dataSize);
for(let i=2;i<range.getLastRow();i++){
if(options.indexOf(val = sheet.getRange(i,1).getValue())===-1){
options.push(val);
}

}
// var dataArray = values.toString().split(",");
// var stringVal = JSON.stringify(dataArray);
// Logger.log(stringVal);
// return JSON.stringify(stringVal); //Modified
Logger.log(options);
return options;

}

function get2nd(first='X60') {
var ss = getSS();
var sheet = ss.getSheetByName('data'); 
var range  = sheet.getRange("A2:A");//or "A2:A" for all data
var vA  = range.getValues();
var dataSize = vA.length;
var options = [];
Logger.log("array size="+ dataSize);
for(let i=2;i<range.getLastRow();i++){
if(sheet.getRange(i,1).getValue() === first){
if(options.indexOf(val = sheet.getRange(i,2).getValue())===-1){
options.push(val);
}
}

}
// var dataArray = values.toString().split(",");
// var stringVal = JSON.stringify(dataArray);
// Logger.log(stringVal);
// return JSON.stringify(stringVal); //Modified
Logger.log(options);
return options;

}

HTML代码:

<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
async function  AddList() {
google.script.run.withSuccessHandler(function(ar) 
{
console.log(ar);

List.length = 0;

let option = document.createElement("option");
option.value = "";
option.text = "Select State";
option.selected =true;
List.appendChild(option);

ar.forEach(function(item, index) 
{    
let option = document.createElement("option");
option.value = item;
option.text = item;
List.appendChild(option);    
});

}).get1st();
// google.script.run.withFailureHandler(function(error) {
//   alert("This action failed to complete. Error: "+ error);
//  }.getCountry();
};

window.onload = function() {
AddList();
}
</script>
</head>
<body>
<form id="form">
<div>
<label for="List">Country<label>
<select id="List" name="List"  onclick="SecondSelect(this.value)" required ></select>
</div>     
<div>
<label for="list2">State<label>
<select id="list2" name="list2" required></select>
</div>     
</form>
<a href="#" id="tButton1">click me</a>
<a href="#" id="tButton2">click me I have a parameter</a>
<script>

// document.addEventListener("DOMContentLoaded", theDomHasLoaded, false);
// window.addEventListener("load", pageFullyLoaded, false);
// function theDomHasLoaded(e) {
//     alert("haha DOM content is loaded");
// }
// function pageFullyLoaded(e){
//    alert("haha page fully loaded");
//   document.getElementbyId("tButton1").onclick = function(){myFunction()};
//   document.getElementbyId("tButton2").onclick = function(){sayHi("Hi")};
//   function myFunction(){
//     alert("my Function is called");
//   }
//   function sayHi(msg){
//     alert(msg);
//   }
// }

function  SecondSelect(country) {
var country = document.getElementById("List");
google.script.run.withSuccessHandler(function(ar) 
{
console.log(ar);

list2.length = 0;

let option = document.createElement("option");
option.value = "";
option.text = "Select State";
option.selected =true;
list2.appendChild(option);

ar.forEach(function(item, index) 
{    
let option = document.createElement("option");
option.value = item;
option.text = item;
list2.appendChild(option);    
});

}).get2nd(country.value);
// google.script.run.withFailureHandler(function(error) {
//   alert("This action failed to complete. Error: "+ error);
//  }.getCountry();
};
</script>     
<!-- <script type="text/javascript" src="cart_Test.js"> </script> -->


<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"> 
</script>
</body>
</html>

主要问题是速度慢。尽管点击几次后,选项显示正确。

这个函数做同样的事情,只是它一次获取所有所需的数据,并从vA中使用它,而不是从循环中运行getValue((

function get2nd(first = 'X60') {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName('data');
var range = sheet.getRange(2,1,sheet.getLastRow()-1,2);//returning first two columns rather than using getValue() to get them from inside the loop
var vA = range.getValues();
var options = [];
vA.forEach(r=>{
if(r[0]==first && !~options.indexOf(r[1])) {
options.push(r[1]);
}
}) 
Logger.log(options);
return options;
}

您可能会发现阅读最佳实践很有价值

位非~

修改点:

  • 在脚本中,getValue()用于函数get1stget2nd的for循环。在这种情况下,处理成本将变得很高。现有的答案已经提到了这一点。参考
  • 在您的情况下,当在第一个下拉列表和第二个下拉列表之间选择值时,单元格值没有改变时,如何从列"中检索所有值;A";以及";B";来自get1st()的电子表格?这样,当选择第二个下拉列表时,可以在不使用google.script.run的情况下放置第二个列表的值。我认为,当google.script.run的使用次数减少时,工艺成本将能够降低

当以上几点反映到您的脚本中时,它变成如下。

谷歌应用程序脚本端:

在这种情况下,使用getValues()的一个函数来代替get1st()get2nd()

function getValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1');
return sheet.getRange("A2:B" + sheet.getLastRow()).getValues();
}

Javascript端:

请按如下方式修改AddListSecondSelect的功能。

AddList()

let values = [];  // Added
function AddList() {
google.script.run.withSuccessHandler(function(ar) {
values = ar;  // Added
List.length = 0;
let option = document.createElement("option");
option.value = "";
option.text = "Select State";
option.selected = true;
List.appendChild(option);
[...new Set(values.map(([a]) => a))]  // Modified
.forEach(a => {
let option = document.createElement("option");
option.value = a;
option.text = a;
List.appendChild(option);
});
}).getValues();
}
window.onload = function() {
AddList();
}

SecondSelect()

function SecondSelect(country) {
var country = document.getElementById("List");
list2.length = 0;
let option = document.createElement("option");
option.value = "";
option.text = "Select State";
option.selected = true;
list2.appendChild(option);
var v = country.value || 'X60';
[...new Set(values.filter(([a]) => a == v).map(([,b]) => b))]  // Modified
.forEach(function(item, index) {
let option = document.createElement("option");
option.value = item;
option.text = item;
list2.appendChild(option);
});
}

最新更新