查询ajax-根据ajax响应更改调用函数的返回值
query ajax- change return value of calling function based on AJAX response?
这个问题已经被问了很多次,答案都是"从成功回调中调用另一个函数"。不幸的是,由于几个原因,我不知道如何在我的情况下让这个答案发挥作用。
对于初学者来说,被调用的ajax是ajaxForm的submit函数。
-
在我调用ajax提交的一个地方,调用函数ITSELF需要返回true或false,这取决于ajax调用的成功与从中返回的一些数据。选项卡小部件本身期望此函数返回true(显示选项卡)或false(不显示选项卡)。由于这个选项卡小部件在我的整个网站上都在使用,所以改变这种行为充其量是很困难的。
-
表单本身可以从多个地方提交,所以我不能简单地从成功处理程序调用这个选项卡函数的其余部分(即使我重写了选项卡处理程序以异步工作),因为当表单在其他地方提交时,这可能不是对成功的适当响应。在这种情况下,我想显示用户单击的选项卡。在另一种情况下,我想重新加载页面或重置表单(新的空白表单),在第三种情况下我想转到另一个页面。但在所有情况下,它都是对提交相同表格的回应
我想我可以做到,当点击时,选项卡总是切换,然后(通过设置标志或其他东西,只有在点击选项卡后才会发生)如果提交不起作用,切换回来,但感觉很糟糕。那么,有什么方法可以让调用函数等待回调完成吗?或者有没有其他方法来构建我没有想到的东西?
编辑:我现在有了当前结构的jsfiddle。一般的想法是,在我知道jquery有一个选项卡小部件之前,我需要选项卡,所以我写了自己的选项卡。它是有效的,所以我认为没有理由改变:-)。
在文档就绪时,具有适当类的每个按钮都会分配一个单击处理程序。流程如下:
- onClick处理程序触发beforeShow事件来运行绑定到选项卡对象的函数(如果有的话)
- beforeShow函数在显示选项卡之前执行所需的任何类型的准备工作(例如加载数据)。如果需要,可以在此处将选项卡对象的"show"数据设置为false,以防止显示选项卡,例如在当前选项卡上检测到需要在切换前修复的错误
- beforeShow函数返回后,onClick处理程序将检查"show"数据是否设置为false,如果没有,则隐藏所有其他选项卡并显示单击的选项卡
因此,我在这里的困境是,为了防止选项卡被显示,我需要在onClick处理程序检查之前(即在beforeShow函数期间)将选项卡对象的"show"数据设置为false。但是由于AJAX回调是异步的,所以直到onClick处理程序完成之后,我才得到AJAX的结果来判断是否应该显示选项卡,从而显示选项卡
正如我所提到的,我可以做一些事情,比如存储当前选项卡,如果ajax结果指示不显示新选项卡,请切换回来,但这对我来说是错误的。
点击处理程序:
function changeTab(){
var jqButton=$(this);
jqButton.data('show',true); //start by assuming we will show the tab.
if(jqButton.hasClass("current")) //don't do anything if switching to the current tab
return;
//run the "before show" function, if any.
jqButton.trigger('beforeShow');
var showTab=jqButton.data('show'); //see if the show flag has been set to false
if(showTab===false) //if no before show function, then showTab is null, not false
return; //if false, then don't show the tab.
$(".tabDiv").hide();
//run any "after hide" scripts bound to the current tab
$('.tabButton.current').trigger('afterHide');
var requestedDiv=jqButton.val(); //the "value" of the tab button is the ID of the tab content div
$("#"+requestedDiv).show(); //may show nothing, if no div exists for the current tab.
$(".tabButton").removeClass("current"); //remove the current class from all tab buttons, so it will only be applied to the new current tab button.
jqButton.addClass("current");
}
这正是您想要的
function tab2BeforeShow(){
var $form = $('#SomeajaxFormObject'); // This is the form you want to submit
// I'd probably show some load indicator here
var result;
$.ajax({
url: $form.attr('action'),
type: 'POST',
data: $form.serialize(),
async: false,
success: function(response) {
result = true; // set the result variable declared in outer function
},
error: function() {
result = false; // bad response - dont show new tab
}
});
// Hide your load indicator now
// since we declared async: false on the ajax request,
// we can be positive that result is set to a boolean value at this point
$(this).data('show', result);
}
我们在表单操作url上发布synchronous
,序列化表单的数据,这样我们就可以使用它进行ajax post。这应该会附带一些小的调整。
这里的关键因素是,我们将data
设置为$form.serialize()
,将async
设置为false,因此浏览器在请求工作时不会继续执行。
如果有任何方法可以避免使用同步ajax,那么您确实应该这样做。如果你无法避免,这应该对你有效。请注意,如果服务器挂起,它也会挂起您的客户端。
这是一个异步实现的方法。
让beforeShow
处理程序接受一个可选的promise参数:
var eventParams = {
promise: null
};
jqButton.trigger('beforeShow', eventParams);
在处理程序本身中,如有必要,创建一个promise:
function tab2BeforeShow(e, eventParams) {
eventParams.promise = $.Deferred();
$.ajax(... async code...
var showTab = [some value received from request];
eventParams.promise.resolve(showTab);
);
}
然后,如果创建了promise,请使用promise链而不是同步函数调用:
// doShowTab is the logic that actually shows/hides a tab
if (eventParams.promise) {
// use promise instead
eventParams.promise.then(doShowTab);
} else {
// beforeShow handler didn't return a promise, assume showTab=true
doShowTab(true);
}
Fiddle:http://jsfiddle.net/669v1Lcd/(我使用setTimeout
来模拟异步请求)
- 如何从模块链中调用函数.导出到节点中
- 调用函数内部的函数
- 在javascript中调用c函数
- DropDownListFor赢得't在更改时调用函数
- Javascript页面调用函数
- 在动画结束之前调用函数
- 允许父窗口在其不同域的子iframe上调用函数
- 运行Infinite Scroll后调用函数时出现问题
- JavaScript:在调用函数的文本输入上按enter键
- 使用大括号和不使用bracs调用函数的区别
- javascript在事件上调用函数
- 从index.html调用函数,该函数无限循环
- 从带参数的字符串变量调用函数中的函数
- 为什么 JS 不在滚动时调用函数
- 是否可以在不更改上下文的情况下调用函数.apply
- 如何在ES6类中使用参数调用函数
- AngularJS:调用函数时编号不更新
- JavaScript中的立即调用函数表达式(IIFE)-传递jQuery
- 在JavaScript中调用函数时自定义此选项
- 调用函数中声明的变量