DOM计时或错误的代码?

时间:2014-08-18 17:02:28

标签: javascript jquery

我有两个多选列表框,第一个允许某人选择一个团队。 第二个显示与团队相关的成员。当选择第一个列表框(团队)时,我进行ajax调用以填充该团队的成员。我也使用所选的库。这一切都正常,但我需要一种方法从列表框中选择值中删除x,以便用户不会认为他们可以从团队中删除成员。

$("#MainContent_lbMembers_chosen a").removeClass("search-choice-close");

当我在控制台窗口中抛出它时,上面的代码可以工作,但是如果我在if条件下使用它,它似乎不起作用:

$("#MainContent_lbTeams").on('change', function() {
            //was a value selected?
            var latest_value = $("option:selected:last", this).val();
            var latest_text = $("option:selected:last", this).text();

            if ($("#MainContent_lbTeams :selected").length > 0) {
                $("#dTeamNotice").show();
                $("#MainContent_lblTeamMembers").text("Members of '" + latest_text + "':");
                PopulateMembers(latest_value);
                $("#MainContent_lbMembers_chosen a").removeClass("search-choice-close");
                $("#trMembers").fadeIn();
            } else {
                //hide it...
                $("#dTeamNotice").css("display", "none");
                $("#trMembers").hide();
            }
        });

基本上,更改事件会获取最近选择的文本和值。如果选择的长度> 0我使用PopulateMembers加载我的团队成员:

 function PopulateMembers(buCompanyTeamID) {
        $('#<%=lbMembers.ClientID %>').empty().append('<option selected="selected" value="0">Loading...</option>');
         $("#<%=lbMembers.ClientID %>").trigger("chosen:updated");
         $.ajax({
             type: "POST",
             url: "/Code/WebServices/Utilities.asmx/GetTeamMembers",
             data: '{buCompanyTeamID: ' + buCompanyTeamID + '}',
             contentType: "application/json; charset=utf-8",
             dataType: "json",
             success: OnMembersPopulated,
             failure: function (response) {
                 alert(response.d);
             }
         });
     }

     function OnMembersPopulated(response) {
         PopulateControl(response.d, $("#<%=lbMembers.ClientID %>"), true);
     }

    function PopulateControl(list, control, selected) {
        if (list.length > 0) {
            control.removeAttr("disabled");
            control.empty().append('<option selected="selected" value="0"></option>');
            $.each(list, function () {
                if(selected)
                    control.append($("<option selected></option>").val(this['Value']).html(this['Text']));
                else
                    control.append($("<option></option>").val(this['Value']).html(this['Text']));
            });
        }
        else {
            control.empty().append('<option selected="selected" value="0"><option>');
        }
        control.trigger("chosen:updated");
    }

但我无法理解为什么在控制台窗口中我可以这样做:

$("#MainContent_lbMembers_chosen a").removeClass("search-choice-close");

它会从所选的选定值中删除x,这样用户就无法移除某个项目,但在if条件下,这不会产生任何影响。

我甚至试过像这样禁用:

$("#MainContent_lbMembers").attr('disabled', true).trigger("chosen:updated");

这只适用于控制台,是时候问题还是别的什么?

1 个答案:

答案 0 :(得分:2)

PopulateMembers()包含异步Ajax调用。所以,如果你期待:

PopulateMembers(latest_value);
$("#MainContent_lbMembers_chosen a").removeClass("search-choice-close");

PopulateMembers()中对ajax调用的结果进行操作,那么确实存在时序问题。 Ajax调用将在PopulateMembers()完成很久之后很久就完成,并且在执行.removeClass()语句之后很久就会完成。

要对PopulateMembers()的结果进行操作,您必须将代码放在该ajax调用的成功处理程序中或重构代码,以便PopulateMembers()在完成后调用回调并且您可以在回调中执行.removeClass()


我建议使用这样的承诺:

// return the ajax promise from PopulateMembers
function PopulateMembers(buCompanyTeamID) {
     $('#<%=lbMembers.ClientID %>').empty().append('<option selected="selected" value="0">Loading...</option>');
     $("#<%=lbMembers.ClientID %>").trigger("chosen:updated");
     return $.ajax({
         type: "POST",
         url: "/Code/WebServices/Utilities.asmx/GetTeamMembers",
         data: '{buCompanyTeamID: ' + buCompanyTeamID + '}',
         contentType: "application/json; charset=utf-8",
         dataType: "json"
     }).then(onMembersPopulated, function (response) {
             alert(response.d);
     });
 }

 $("#MainContent_lbTeams").on('change', function() {
        //was a value selected?
        var latest_value = $("option:selected:last", this).val();
        var latest_text = $("option:selected:last", this).text();

        if ($("#MainContent_lbTeams :selected").length > 0) {
            $("#dTeamNotice").show();
            $("#MainContent_lblTeamMembers").text("Members of '" + latest_text + "':");
            // act only when the returned promise is resolved
            PopulateMembers(latest_value).then(function() {
                $("#MainContent_lbMembers_chosen a").removeClass("search-choice-close");
                $("#trMembers").fadeIn();
            });
        } else {
            //hide it...
            $("#dTeamNotice").css("display", "none");
            $("#trMembers").hide();
        }
    });