我正在使用 jQuery Ajax request在原型(prototype)函数中。我希望用户能够将自己的 complete
和 beforeSend
函数传递到此函数中。然后,这些用户函数应该从选项中提取出来,并放入我自己的 beforeSend
和 complete
函数中,这样我就可以在触发用户函数之前在其中执行一些系统操作。
我做了这个 fiddle 来澄清。查看“带选项”链接如何按预期工作,而“不带选项”链接如何不按预期工作。单击几次即可明白我的意思:
http://jsfiddle.net/xwmoaepc/1/
function jBox() {
this.options = {
ajax: {
url: 'http://stephanwagner.me/ajax/0/SYSTEM RESPONSE',
data: ''
}
}
}
jBox.prototype.ajax = function (options) {
$('#log').append('<div class="first">function prototype.ajax started<div>');
// Abort running ajax call
this.ajaxRequest && this.ajaxRequest.abort();
// Merge options
var ajaxOptions = jQuery.extend(this.options.ajax, (options || {}));
// Extract events
var beforeSend = ajaxOptions.beforeSend || function () {};
var complete = ajaxOptions.complete || function () {};
// Set new beforeSend event
ajaxOptions.beforeSend = function () {
$('#log').append('<div style="color: #d66">SYSTEM-beforeSend<div>');
(beforeSend.bind(this))();
}.bind(this);
// Set new complete event
ajaxOptions.complete = function (response) {
$('#log').append('<div style="color: #6d6">SYSTEM-complete: ' + response.responseText + '<div>');
(complete.bind(this))(response);
}.bind(this);
// Send new ajax request
this.ajaxRequest = jQuery.ajax(ajaxOptions);
};
// Create instance
var jBox = new jBox();
// This function is working!
function triggerAjaxOpt() {
var userOptions = {
url: 'http://stephanwagner.me/ajax/0/USER RESPONSE: ' + $('input').val(),
beforeSend: function () {
$('#log').append('<div style="color: #66d">USER-beforeSend<div>');
},
complete: function () {
$('#log').append('<div style="color: #66d">USER-complete<div>');
}
};
jBox.ajax(userOptions);
}
// This function will have more and more beforeSend and complete outputs
function triggerAjax() {
jBox.ajax();
}
另请注意,当您单击无效链接后将数字 2 更改为 3 时,不会更改响应。
编辑:它现在正在工作,这就是我最终得到的结果: http://jsfiddle.net/xwmoaepc/3/
最佳答案
试试这个,它会起作用:
var ajaxOptions = jQuery.extend((options || {}), this.options.ajax);
如果你将 this.options.ajax 作为扩展的第一个参数,它会改变 this.options.ajax 请参阅下面的代码:
//see what the following line does when second argument is an object
// not having beforesend (if it has then it'll be overwritten)
//var ajaxOptions = jQuery.extend(this.options.ajax, (options || {}));
var org = {id:"org"}
var copy = jQuery.extend(org,{});
console.log(copy===org);//true as copy is a reference to org
copy.id="copy";//mutating members in copy affect org
console.log(org.id);//=copy
现在声明:
ajaxOptions.beforeSend = function () { ...
等同于:
this.options.ajax.beforeSend = function() { ...
因此第一次它将是未定义的,局部变量 beforeSend 将是一个空函数。
第二次局部变量beforeSend将是this.options.ajax.beforesend,并且this.options.ajax.beforesend被重新分配一个调用局部变量beforesend的函数,该函数将调用闭包beforesent(空函数)
第三次调用ajax...
关于javascript - 为什么在没有设置选项的情况下AJAX beforeSend和complete函数会被多次触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25202669/