jQuery.ajax() 并不总是有效吗?容易失火吗?

Posted

技术标签:

【中文标题】jQuery.ajax() 并不总是有效吗?容易失火吗?【英文标题】:Does jQuery.ajax() not always work? Is it prone to miss-fire? 【发布时间】:2015-02-16 07:07:33 【问题描述】:

我的页面上有一个 $.ajax 函数,用于根据服务类型选择填充设施下拉列表。如果我在两个选项之间来回更改服务类型选择,设施下拉列表中的值将随机保持不变并且不会改变。有没有办法防止这种情况?我做错了吗?

javascript

function hydrateFacilityDropDownList() 
        var hiddenserviceTypeID = document.getElementById('<%=serviceTypeID.ClientID%>');
        var clientContractID = document.getElementById('<%=clientContractID.ClientID%>').value;
        var serviceDate = document.getElementById('<%=selectedServiceDate.ClientID%>').value;
        var tableName = "resultTable";

        $.ajax(
            type: 'POST',
            beforeSend: function () 

            ,
            url: '<%= ResolveUrl("AddEditService.aspx/HydrateFacilityDropDownList") %>',
            data: JSON.stringify( serviceTypeID: TryParseInt(hiddenserviceTypeID.value, 0), clientContractID: TryParseInt(clientContractID, 0), serviceDate: serviceDate, tableName: tableName ),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (data) 
                a(data);
            
            ,error: function () 
                alert('HydrateFacilityDropDownList error');
            
            , complete: function () 

            
        );
    

function a(data) 
        var facilityDropDownList = $get('<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>');
        var selectedFacilityID = $get('<%= selectedFacilityID.ClientID%>').value;
        var tableName = "resultTable";

        if (facilityDropDownList.value != "") 
            selectedFacilityID = facilityDropDownList.value;
        

        $(facilityDropDownList).empty();
        $(facilityDropDownList).prepend($('<option />',  value: "", text: "", selected: "selected" ));
        $(data.d).find(tableName).each(function () 
            var OptionValue = $(this).find('OptionValue').text();
            var OptionText = $(this).find('OptionText').text();

            var option = $("<option>" + OptionText + "</option>");
            option.attr("value", OptionValue);

            $(facilityDropDownList).append(option);
        );

        if ($(facilityDropDownList)[0].options.length > 1) 
            if ($(facilityDropDownList)[0].options[1].text == "In Home") 
                $(facilityDropDownList)[0].selectedIndex = 1;
             
        

        if (TryParseInt(selectedFacilityID, 0) > 0) 
            $(facilityDropDownList)[0].value = selectedFacilityID;
        

        facilityDropDownList_OnChange();
    

代码背后

[WebMethod]
    public static string HydrateFacilityDropDownList(int serviceTypeID, int clientContractID, DateTime serviceDate, string tableName)
    

        List<PackageAndServiceItemContent> svcItems = ServiceItemContents;
        List<Facility> facilities = Facility.GetAllFacilities().ToList();
        if (svcItems != null)
        
            // Filter results
            if (svcItems.Any(si => si.RequireFacilitySelection))
            
                facilities = facilities.Where(f => f.FacilityTypeID > 0).ToList();
            
            else
            
                facilities = facilities.Where(f => f.FacilityTypeID == 0).ToList();
            

            if (serviceTypeID == 0)
            
                facilities.Clear();
            
        
        return ConvertToXMLForDropDownList(tableName, facilities);
    

public static string ConvertToXMLForDropDownList<T>(string tableName, T genList)
    
        // Create dummy table
        DataTable dt = new DataTable(tableName);
        dt.Columns.Add("OptionValue");
        dt.Columns.Add("OptionText");

        // Hydrate dummy table with filtered results
        if (genList is List<Facility>)
        
            foreach (Facility facility in genList as List<Facility>)
            
                dt.Rows.Add(Convert.ToString(facility.ID), facility.FacilityName);
            
        

        if (genList is List<EmployeeIDAndName>)
        
            foreach (EmployeeIDAndName employeeIdAndName in genList as List<EmployeeIDAndName>)
            
                dt.Rows.Add(Convert.ToString(employeeIdAndName.EmployeeID), employeeIdAndName.EmployeeName);
            
        

        // Convert results to string to be parsed in jquery
        string result;
        using (StringWriter sw = new StringWriter())
        
            dt.WriteXml(sw);
            result = sw.ToString();
        

        return result;
    

【问题讨论】:

恰恰相反,ajax 总是可以工作的,如果你做对了,并且有连接。 当您更改时旧请求是否处于待处理状态,因此您在多个调用之间有一点竞争条件。我没有看到你中止之前的通话。 【参考方案1】:

$get 返回 XHR 对象而不是成功调用的返回值,并且 $get 函数不是同步的,因此您应该等待成功并检查调用返回的数据

这两行的作用与您的预期不同

var facilityDropDownList = $get('<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>');
var selectedFacilityID = $get('<%= selectedFacilityID.ClientID%>').value;

改成类似这样的东西

var facilityDropDownList;

$.ajax(
      url: '<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>',
      type: 'get',
      dataType: 'html',
      async: false,
      success: function(data) 
          facilityDropDownList= data;
       
 );

【讨论】:

在 15 次尝试中大约有 1 次没有正确返回值时,$get 怎么会成为问题?

以上是关于jQuery.ajax() 并不总是有效吗?容易失火吗?的主要内容,如果未能解决你的问题,请参考以下文章

这是 jquery.ajax() 中的有效 url 参数吗?

在 asp.net webservices 中使用 jQuery AJAX 总是出错:而不是成功:

为啥 QSplashscreen 并不总是有效?

条件变量并不总是有效

removeFromSuperview() 并不总是有效

为啥 constexpr 隐式转换并不总是有效?