Javascript — проблема с использованием forin для перебора объекта

У меня есть динамически сгенерированный объект, который выглядит так:

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

Я пытаюсь использовать его для раскрашивания карты с помощью этого плагина и атрибут 'colors' во время вызова плагина. Так:

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

Но это не цвет в странах. Когда я жестко кодирую это, он работает нормально, но он должен быть динамически сгенерирован для этого проекта, поэтому что-то вроде этого не будет работать для меня (хотя на самом деле это окрашивает карту):

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

Я проследил проблему достаточно глубоко в плагине, чтобы найти, что она как-то связана с этим циклом:

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. Я снова путаю различия между Arrays() и Objects() в javascript.
  3. Возможно, это проблема масштаба?
  4. Некоторая комбинация всего вышеперечисленного.

EDIT #1: я переместил свой дополнительный вопрос об объектах в консоли в Firebug в новое сообщение ЗДЕСЬ. Этот вопрос более конкретно относится к 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();

Затем эта функция вызывается по событию щелчка флажка в другом месте страницы. Объекты iniDensityData и colorArray объявлены в заголовке 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>

person Tim    schedule 31.07.2012    source источник
comment
вы определенно путаете [] и {}, по крайней мере. {} не имеет свойства длины, если вы не добавите его явно.   -  person Dan Davies Brackett    schedule 01.08.2012
comment
также: когда вы устанавливаете точку останова в цикле for, является ли значение цветов таким, как вы ожидаете?   -  person Dan Davies Brackett    schedule 01.08.2012
comment
Просто снимаем в темноте, здесь... вы упомянули, что используете функцию jQuery.each. Вы случайно не используете ключевое слово this внутри этой функции? например this.countries? this неправильное связывание является одной из наиболее распространенных причин ошибок в JavaScript.   -  person rybosome    schedule 01.08.2012
comment
@DanDaviesBrackett да, я почти уверен, что хочу использовать {} (объект, верно?), И этот .length для этого не подойдет, но, конечно же, цикл for/in должен?   -  person Tim    schedule 01.08.2012
comment
@HerroRygar Почти уверен, что все сделано правильно, при успешном обратном вызове ajax-вызова jQuery я делаю следующее: $(xml).find("Country").each(function () { var cCode = $(this).find("CountryCode").text(); ...some more stuff }, а затем заполняю colorArray следующим образом: colorArray[cCode] = cColor;   -  person Tim    schedule 01.08.2012
comment
А как насчет переменной colorArray (хотя на самом деле это объект)? Что можно сказать о масштабах этого? Было бы неплохо, если бы вы разместили больше кода, чтобы получить полный контекст. Использование инструментов разработчика также может помочь вам копнуть глубже; поместите следующий оператор прямо перед вызовом функции vectorMap: console.log(colorArray);. Это запишет в консоль отладки вашего браузера содержимое объекта colorArray. Гугл инструкция как подтянуть консоль. Я предполагаю, что этот объект будет либо {},null, либо undefined.   -  person rybosome    schedule 01.08.2012
comment
... но да, если бы вы могли опубликовать весь рассматриваемый блок кода, это значительно облегчило бы диагностику проблемы с областью действия.   -  person rybosome    schedule 01.08.2012
comment
Вы можете подумать о том, чтобы не вызывать Object в Array. Массив в javascript использует квадратные скобки var arr = [];. Называя это массивом, мы думаем, что вы запутались...   -  person ErikE    schedule 01.08.2012


Ответы (1)


Решено! Первоначально я вызывал функцию 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();
person Tim    schedule 01.08.2012