我们编写了一个通用的jQuery操作,该操作绑定到一个选择的国家/地区列表。它必然会选择国家;当它被改变时,调用服务器来获取状态......
$('#' + countryElementID).change(function () {
var countryID = $('#' + countryElementID).val();
$.ajax({
type: 'POST',
url: '/App/GetStatesByCountry',
data: {
id: countryID
},
dataType: 'json',
success: function (result) {
// build HTML replace via .html
},
failure: function (result) {
// ...
}
});
});
以下是触发此操作的代码......
var populateCompanyInfo = function (resultData) {
var populateList = {
CompanyName: 'input',
Address1: 'input',
Address2: 'input',
City: 'input',
Zip: 'input',
Email: 'input',
Phone: 'input',
Fax: 'input',
CountryID: 'select',
StateID: 'select',
Active: 'toggle'
}
$.each(populateList, function (name, value) {
var a = eval('resultData.' + name);
var sectionID = 'RealtyCompany';
if (a != null || a != '') {
if (value == 'input') {
// ...
}
if (value == 'select') {
var a = eval('resultData.' + name);
$('#select' + sectionID + name).val(a);
$('#select' + sectionID + name).trigger('change');
}
if (value == 'toggle') {
// ...
}
}
});
我遇到的问题是它在填充状态之前选择StateID(从更改国家/地区下拉列表触发)。
我是否可以在Country下拉列表的泛型操作中传递一个变量,该变量基本上会等到变量传递完毕?我试着想办法在jQuery中加入一个延迟的动作,但是我很难找到一种方法来做到这一点。
答案 0 :(得分:0)
看了这个小时后,一分钱掉了 - 这就是我认为我已经渗透了这个问题。我是否有书面的工作答案还有待观察。
无论你采用哪种方式,关键是让jqXHR'承诺'(通过AJAX获取所选国家的状态)可用于其他范围。我选择通过设置强加在国家/地区选择元素上的jQuery .data('fetchData')
对象的属性来执行此操作。
然后,由于.each(populateList, ...)
循环的工作方式(我还没有尝试改变它),jqXHR也需要作为循环内两个分支之间的外部成员传递。可以采用其他方法,但我发现的所有方法至少都是混乱的。
由于不保证.data()
对象存在,因此需要相当大的安全性来增加脚本的批量。很可能有一种更简单的方法可以用更少的代码实现同样的目的。
以下是代码:
$(function() {
var countryElementID = 'selectRealtyCompanyCountryID';
$('#' + countryElementID).change(function () {
var $this = $(this);
var jqXHR = $.ajax({
type: 'POST',
url: '/App/GetStatesByCountry',
data: { id: $this.val() },
dataType: 'json',
success: function (result) {
// Build HTML replace via .html()
},
failure: function (result) {
// Generic error handler
alert('Generic error handler');
}
});
var fetchData = $this.data('fetchStates');// May of may not exist.
if(fetchData) fetchData.jqXHR = jqXHR;//Make the jqXHR available to other scopes via the DOM.
});
var populateCompanyInfo = function (resultData) {
var populateList = {
CompanyName: 'input',
Address1: 'input',
Address2: 'input',
City: 'input',
Zip: 'input',
Email: 'input',
Phone: 'input',
Fax: 'input',
CountryID: 'select',
StateID: 'select',
Active: 'toggle'
}
var fetchPromise = null;
$.each(populateList, function (name, value) {
var a = resultData[name];
var sectionID = 'RealtyCompany';
if(a) {
if (value == 'input') {
// ...
}
if (value == 'select' && name == 'CountryID') {
//Branch for the CountryID select menu
var $el = $('#select' + sectionID + name);
var fetchData = $el.data('fetchStates');
if(!fetchData) {
$el.data('fetchStates', {});
}
if(fetchData.jqXHR && fetchData.jqXHR.abort) {//safety
fetchData.jqXHR.abort();//Kill any outstanding ajax requests of the same type.
}
$el.val(a).trigger('change');
fetchPromise = data.jqXHR;//Make the new jqXHR object available to the 'StateID' branch next time round the .each loop.
}
if (value == 'select' && name == 'StateID') {
//Branch for the StateID select menu
if(fetchPromise && fetchPromise.done) {//May of may not be defined.
fetchPromise.done(function(data, textStatus, jqXHR) {
// At this point the States element is freshly populated with states.
// Here, do whatever is necessary once the States element
// eg. set its .val() then trigger its 'change' event.
}).fail(function(jqXHR, textStatus, errorThrown) {
// Display error message?
// Set the States element to a default value?
alert('Specific error handler');
});
}
}
if (value == 'toggle') {
//...
}
}
});
}
});
经过测试以消除语法错误 - 仅此而已
是的,它可以简化 - here's some better code。您将看到由于ajax失败而导致的错误消息 - 我还没有完全模拟获取状态。但错误信息很好 - 它们意味着事件的顺序是正确的。