我试图弄清楚如何在不使用太多if语句的情况下调用项目中的函数。使用if语句的概念效果很好。但是,每次创建新函数调用时,都必须编写新的if语句。我希望做的是在JSON数组中添加新的函数调用,然后以这种方式调用我的函数。我目前正在通过D3的方式从JSON数组加载数据,希望以此方式添加函数调用。下面是使用if语句的工作概念的副本,效果很好。
var funcData;
d3.csv("data/pointData5.csv", function(error, data) {
funcData = JSON.parse(JSON.stringify(data));
console.log(funcData);
var select = d3.select("#selectL")
.append("div")
.append("select")
select
.on("change", function() {
var v = d3.select(this).property("value");
if (v == 2) {
updateDataA();
}
if (v == 3) {
updateDataB();
}
if (v == 4) {
updateDataC();
}
if (v == 5) {
updateDataD();
}
})
select.selectAll("option")
.data(data)
.enter()
.append("option")
.attr('class', function(d,i) { return 'option' + i;})
.attr("value", function (d) { return d.value; })
.text(function (d) { return d.label; })
});
下面是我要努力工作的概念,但似乎无法工作。正在加载函数名称,但不会像上面的脚本那样调用函数。
var funcData;
d3.csv("data/pointData5.csv", function(error, data) {
funcData = JSON.parse(JSON.stringify(data));
console.log(funcData);
var select = d3.select("#selectL")
.append("div")
.append("select")
select
.on("change", function() {
var v = d3.select(this).property("value");
for (var i = 1; i < funcData.length; i++)
if (v == i && funcData[i].dataF) {
console.log(funcData[i].dataF);
funcData[i].dataF;
}
})
select.selectAll("option")
.data(data)
.enter()
.append("option")
.attr('class', function(d,i) { return 'option' + i;})
.attr("value", function (d) { return d.value; })
.text(function (d) { return d.label; })
});
如果有人可以提供解决方案,或者甚至可以实现此概念,我将非常感谢。预先谢谢你。
该函数调用的新增版本:
updateDataA();
function updateDataA() {
updateData("gTank.png");
}
function updateDataB() {
updateData("bTank.png");
}
function updateDataC() {
updateData("diamond.svg");
}
////////////Add Markers to Map//////////////////
function updateData(url) {
removeMarkers()
omnivore.csv('data/pointData5.csv')
.on('ready', function(layer) {
this.eachLayer(function(marker) {
if (marker.toGeoJSON().properties.graphic != url)
marker.remove();
//////////////////////////////////////////////////////////////
// Add a flyTo button
//////////////////////////////////////////////////////////////
var button = document.createElement("button");
button.className += " myBtns";
if(marker.toGeoJSON().properties.graphic == url) {
button.innerHTML =
marker.toGeoJSON().properties.cityName;
$('.zoomPoint').append(button);
}
// button.innerHTML = marker.toGeoJSON().properties.cityName;
button.addEventListener("click", function (event) {
event.preventDefault();
// map.flyTo(layer.getLatLng(), 5); // This works obviously,
but just to demonstrate use of xy conversion:
map.flyTo(xy(marker.toGeoJSON().geometry.coordinates), 9, {
animate: true,
duration: 2.5
});
map.once("moveend", function () {
marker.openPopup();
});
});
//////////////////////////////////////////////////////////////
//Load Icons from CSV file
var customIcon = L.icon({
iconUrl: 'graphic/' +
marker.toGeoJSON().properties.graphic,//add graphic from CSV file
iconSize: [20, 10 ], //size of the icon in pixels
iconAnchor: [9, 9], //point of the icon which will
correspond to marker's location (the center)
popupAnchor: [0, 0] //point from which the popup should
open relative to the iconAnchor
});
//Add ID to each image - can now style each icon with CSS
$('#map').find('img').each(function (i) {
$(this).attr('id', 'img_');
});
$(".content ").find(".myBtns:first-child").prop("disabled", true);
//change the icons for each point on the map
marker.setIcon(customIcon);
//create popup with text and image - click image in popup,
large image displays in fancybox
var popupText =
marker.bindPopup('<strong>' +
marker.toGeoJSON().properties.cityName + '</strong>' + ', ' + '</br>'
+ marker.toGeoJSON().properties.discrip + "<br /><a class='fancybox-
thumb' ' style='width:150px;' rel='fancybox-button' rel='fancybox-
thumb' data-fancybox-group='"+ marker.toGeoJSON().properties.popup +"'
title='" + marker.toGeoJSON().properties.discrip + " '
href='graphic/"+
marker.toGeoJSON().properties.popup + "' ><img src='graphic/" +
marker.toGeoJSON().properties.popup + "' alt='Image' ' s
style='width:150px;'
></a>" + "<br/><a href='http://www.google.com'
target='_blank'>Cedellion Report</a>");
});
}).addTo(map);
}
答案 0 :(得分:1)
您可以使用 eval()
,但不建议这样做。还有其他选择可以执行此操作,但是很可能您可以在此处进行一些重新架构。您的updateDataA()
,updateDataB()
和updateDataC()
函数有什么作用?它们彼此有何不同?您很可能可以重构为单个updateData
函数,该函数采用基于当前数组元素的参数并相应地更新数据。在我完全回答您的问题之前,我需要更多详细信息。
执行此操作的最佳方法是将URL存储在JSON数组中(例如"url": "gTank.png"
),然后调用传递到updateData()
属性中的url
函数。
let url = d3.select(this).property("url");
updateData(url);
这可能是最佳做法,因为评估是一种安全风险,因此不建议使用。
答案 1 :(得分:0)
您可以将函数存储在数组中。但是有必要在调用中添加括号。
尝试
if (v == i && funcData[i].dataF) {
console.log(funcData[i].dataF);
funcData[i].dataF(); // see the parentheses
}
您还可以使用此代码在调用之前检查它是否为函数
if(typeof funcData[i].dataF === 'function') {
}
示例
let funcs = [
(a, b) => { return a+b; },
(a, b) => { return a-b; },
() => { return true; }
];
funcs[0](2, 4); // return 6
funcs[1](2, 4); // return -2
funcs[2](); // return true
或
let funcs = {
addition: (a, b) => { return a+b; },
soustraction: (a, b) => { return a-b; }
};
funcs.addition(2, 4); // return 6
funcs['addition'](2, 4); // return 6
funcs.soustraction(2, 4); // return -2
funcs['soustraction'](2, 4); // return -2
答案 2 :(得分:0)
经过更多研究,我找到了我的解决方案eval()。这是M. Page和Richik的建议。...谢谢。为了完成我要完成的任务,我在循环中添加了我的函数,例如eval('('+ funcData [i] .dataF +')');一切都如我所愿。谢谢大家让我走上正确的道路。