如何从JSON数组调用函数

时间:2019-01-20 15:00:33

标签: javascript json d3.js

我试图弄清楚如何在不使用太多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; })
});

下面是我的JSON数组的屏幕截图。
Screen Capture of JSON Object from Console

如果有人可以提供解决方案,或者甚至可以实现此概念,我将非常感谢。预先谢谢你。

该函数调用的新增版本:

 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);
    }

3 个答案:

答案 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 +')');一切都如我所愿。谢谢大家让我走上正确的道路。