Javascript - 无法使用for ...来遍历对象

时间:2012-07-31 22:48:22

标签: javascript jvectormap

我有一个动态生成的对象,如下所示:

colorArray = { 
    AR: "#8BBDE1", 
    AU: "#135D9E", 
    AT: "#8BBDE1",
    ... }

我正在尝试使用它在调用插件期间使用this plugin和'colors'属性为地图着色。像这样:

$('#iniDensityMap').vectorMap({
    backgroundColor: '#c2e2f2',
    colors: colorArray,
    ... (some other params)
});

但它在各国都没有颜色。当我硬编码时,它工作正常 - 但它必须为这个项目动态生成,所以这样的东西对我来说不起作用(虽然它确实为地图着色):

$('#iniDensityMap').vectorMap({
    backgroundColor: '#c2e2f2',
    colors: { AR: "#8BBDE1", AU: "#135D9E", AT: "#8BBDE1" },
    ... (some other params)
});

我已经将问题追溯到插件中,发现它与此循环有关:<​​/ p>

setColors: function(key, color) {
  if (typeof key == 'string') {
    this.countries[key].setFill(color);
  } else {

    var colors = key; //This is the parameter passed through to the plugin

    for (var code in colors) {

      //THIS WILL NOT GET CALLED

      if (this.countries[code]) {
        this.countries[code].setFill(colors[code]);
      }
    }
  }
},

我也试过在插件之外迭代遍历colorArray对象,我遇到了同样的问题。无论什么位于 for(var x in obj)内都没有触发。我还注意到colorArray.length返回 undefined 。另一个重要的注意事项是我在一个单独的调用中实例化了var colorArray = {};,试图确保它位于全局范围内并且能够被操纵。

我认为问题是:

  1. 我动态填充对象的方式 - colorArray[cCode] = cColor;(在jQuery .each调用中)
  2. 我再次混淆了Javascript
  3. 中Arrays()和Objects()之间的差异
  4. 这可能是一个范围问题?
  5. 上述所有内容的组合。
  6. 编辑#1:我已将有关Firebug中控制台中的对象的其他问题移至新帖子HERE。这个问题更具体地涉及Firebug而不是我在这里询问的潜在JS问题。

    编辑#2:其他信息 这是我用来动态填充对象的代码:

    function parseDensityMapXML() {
    $.ajax({
        type: "GET",
        url: "media/XML/mapCountryData.xml",
        dataType: "xml",
        success: function (xml) {
            $(xml).find("Country").each(function () {
                var cName = $(this).find("Name").text();
                var cIniCount = $(this).find("InitiativeCount").text();
                var cUrl = $(this).find("SearchURL").text();
                var cCode = $(this).find("CountryCode").text();
    
                //Populate the JS Object
                iniDensityData[cCode] = { "initiatives": cIniCount, "url": cUrl, "name": cName };
                //set colors according to values of initiatives count
                colorArray[cCode] = getCountryColor(cIniCount);
            });
        }
    });
    } //end function parseDensityMapXML();
    

    然后在页面上其他位置的复选框的单击事件上调用此函数。对象iniDensityDatacolorArray在html文件的头部声明 - 希望将它们保持在全局范围内:

    <script type="text/javascript">
        //Initialize a bunch of variables in the global scope
        iniDensityData = {};
        colorArray = {};
    </script>
    

    最后,这是正在阅读的XML文件的片段:

    <?xml version="1.0" encoding="utf-8"?>
    <icapCountryData>
      <Country>
        <Name>Albania</Name>
        <CountryCode>AL</CountryCode>
        <InitiativeCount>7</InitiativeCount>
        <SearchURL>~/advance_search.aspx?search=6</SearchURL>
      </Country>
      <Country>
        <Name>Argentina</Name>
        <CountryCode>AR</CountryCode>
        <InitiativeCount>15</InitiativeCount>
        <SearchURL>~/advance_search.aspx?search=11</SearchURL>
      </Country>
      ... and so on ...
    </icapCountryData>
    

1 个答案:

答案 0 :(得分:3)

解决了它!最初,我正在调用函数parseDensityMapXML(),然后在调用另一个函数loadDensityMapXML()之后立即调用第一个函数中动态创建的对象并迭代通过它。问题是,它从第一个函数中被称为回调,所以在构建对象之前就已经开始了。

要修复,我刚刚修改了上面提到的第一个函数,在 .each()完成创建对象之后调用第二个函数

function parseDensityMapXML() {
$.ajax({
    type: "GET",
    url: "media/XML/mapCountryData.xml",
    dataType: "xml",
    success: function (xml) {
        $(xml).find("Country").each(function () {
            var cName = $(this).find("Name").text();
            var cIniCount = $(this).find("InitiativeCount").text();
            var cUrl = $(this).find("SearchURL").text();
            var cCode = $(this).find("CountryCode").text();

            //Populate the JS Object
            iniDensityData[cCode] = { "initiatives": cIniCount, "url": cUrl, "name": cName };
            //set colors according to values of initiatives count
            colorArray[cCode] = getCountryColor(cIniCount);
        });

        /* and then call the jVectorMap plugin - this MUST be done as a callback
           after the above parsing.  If called separately, it will fire before the
           objects iniDensityData and colorArray are created! */
        loadDensityMapXML();
    }
});
} //end function parseDensityMapXML();