使用jQuery加载选择:缺少元素

时间:2015-05-03 23:43:02

标签: jquery xml html-select

这个问题非常奇怪。我正在试图加载带有城镇列表的选择。我有一个函数,从.xml文件收集城镇并返回一个数组,以及另一个调用前者的函数,并使用检索到的城镇加载选择。解析xml的函数工作正常。但是加载选择的功能并没有;它只加载select中的第一个元素(xml中有10个城镇,由解析xml文件的函数成功检索)。更重要的是,如果我只是使用firebug调试它添加几个断点,或者如果我在函数中添加一个警告来显示城镇阵列长度,那么它就会神奇地"作品。这很荒谬,很烦人。

这里有我的代码:

function PrecargarCampos(){
/*this function loads the select */

    var pueblos = getMunicipios(); //retrieves towns from an .xml
    $(".municipio").each(function() {
        for (i=0;i<pueblos.length;i++) {
            var option = "<option value='" + pueblos[i] + "'>" + pueblos[i] + "</option>";
            $(this).append(option);
        }
    });
}

然后,如果我添加警报......

function PrecargarCampos(){
/* this function loads the select */

    var pueblos = getMunicipios(); //retrieves towns from an .xml
    **alert("Number of towns" + pueblos.length);**
    $(".municipio").each(function() {
        for (i=0;i<pueblos.length;i++) {
            var option = "<option value='" + pueblos[i] + "'>" + pueblos[i] + "</option>";
            $(this).append(option);
        }
    });
}

......它令人难以置信地工作。

我还将添加从.xml中检索城镇的函数代码。单独调试后,似乎工作正常:

function getMunicipios () {
/* retrieves town list from .xml */

    var municipios = [];
    municipios.push("Foo town");
    var url = getURLroot() + "/data/lists/municip.xml"; //get .xml path

    $.get(url, function (xml) {
        $(xml).find("municip").each(function () {
            var nom = $(this).find('nom').text();
            var prov = $(this).find('prov').text();
            var muni = nom + " (" + prov + ")";
            municipios.push(muni);
        });
    });

    return municipios; 
}

var municipios是一个应该有10个项目的数组,但最后,select只会加载&#34; Foo town&#34;值。正如我所说的,如果我打开调试器或添加一个简单的警报,则选择正确加载了10个城镇。

我完全糊涂了,不知道如何解决它。我会感谢任何建议。谢谢。

3 个答案:

答案 0 :(得分:0)

您选择拥有ID吗?

for(i=0;i<data.length;i++){
 $("#id_of_select").append("<option value='"+pueblos[i].nombre+"'>"Pueblo"</option>");  
 }

答案 1 :(得分:0)

我会说你的代码没有像你期望的那样以“线性”的方式运行。 那是因为你在getMunicipios()中的jQuery.get()中使用了“onSuccess”函数。它会做:

var municipios = [];
municipios.push("Foo town");
var url = getURLroot() + "/data/lists/municip.xml"; //get .xml path

然后它将直接转到:

return municipios;

,只有这样,它才能做到:

$.get(url, function (xml) {
    $(xml).find("municip").each(function () {
        var nom = $(this).find('nom').text();
        var prov = $(this).find('prov').text();
        var muni = nom + " (" + prov + ")";
        municipios.push(muni);
    });
});


因此,如果您过早使用变量 pueblos ,则您的列表将没有时间填写。此时,您将只获得添加的第一个元素。
要检查我是否正确,您可以在$.get(url, function (xml) {return municipios;之前发出警报,然后您将获得运行代码的顺序。

不过,我可能错了。

你可以尝试:

function PrecargarCampos(){
/*this function loads the select */

    getMunicipios(function(pueblos) {
        $(".municipio").each(function() {
            for (i=0;i<pueblos.length;i++) {
                var option = "<option value='" + pueblos[i] + "'>" + pueblos[i] + "</option>";
                $(this).append(option);
            }
        });
    });
}


function getMunicipios (callback) {
/* retrieves town list from .xml */

    var municipios = [];
    municipios.push("Foo town");
    var url = getURLroot() + "/data/lists/municip.xml"; //get .xml path

    $.get(url, function (xml) {
        $(xml).find("municip").each(function () {
            var nom = $(this).find('nom').text();
            var prov = $(this).find('prov').text();
            var muni = nom + " (" + prov + ")";
            municipios.push(muni);
        });
        callback(municipios);
    }); 
}

答案 2 :(得分:0)

根据里克的建议,我最终得到了这个:

function PrecargarCampos(){

var pueblos = getMunicipios();
setTimeout(function(){
     $(".municipio").each(function() {
        for (i=0;i<pueblos.length;i++) {
           var option = "<option value='" + pueblos[i] + "'>" + pueblos[i] + "</option>";
           $(this).append(option);
        }
        $(this).append("<option value='Foo town'>Foo town</option>");
     });
  }, 1000); 
}

这对我有用。 setTimeout允许函数getMunicpios在使用返回的数组(pueblos)加载select之前执行完整的迭代。