我在表单中使用Plupload file uploader。我想自定义它,以便在提交表单时,即单击“提交”按钮时,首先发生的是文件上传,然后是提交表单。
据我所知,我可能错了,但似乎调用uploader.start()
是异步函数调用。因此,目前,上传将开始,表单将在文件上传之前提交。问题是我无法控制这个函数调用。
我最近阅读了关于new release of jQuery 1.5和新Deferred Object的信息,看起来这有可能帮助我解决这个问题。有没有办法等待异步函数调用完成其工作,然后在调用后继续执行代码。所以我正在寻找类似下面的伪代码......
var uploader = $('#plupload_container').pluploadQueue();
$('#submitButton').click(function() {
// if there are files to be uploaded, do it
if (uploader.files.length > 0) {
// make the call and wait for the uploader to finish
uploader.start();
while ( the uploading is not done ) {
wait for the uploader to finish
}
// continue with submission
}
});
有没有办法“等待”uploader.start()
完成,实际上是在click事件处理程序上暂停,这样所有文件都可以先上传,然后其余的click事件处理程序就可以完成了执行?我尝试了以下内容,但在文件上传完成之前打印了“完成”...
$.when(uploader.start()).then(function () {
console.log("done")
});
另一个有用的信息...我可以将某些事件绑定到此uploader
对象实例,例如“UploadProgress”或“UploadComplete”。例如,我可以以某种方式使用延迟对象来捕获“UploadComplete”事件触发的时间吗?是否有AJAX-y方法可以做到这一点?
感谢。
答案 0 :(得分:5)
您的问题是虽然uploader.start
执行了异步操作,但uploader.start
必须返回jquery $.deferred
对象。
来自您的上传器插件的最新来源:
/**
* Starts uploading the queued files.
*
* @method start
*/
start : function() {
if (this.state != plupload.STARTED) {
this.state = plupload.STARTED;
this.trigger("StateChanged");
uploadNext.call(this);
}
},
因此它不会返回延迟对象。相反,在uploadNext
函数中有这行代码:
this.trigger("UploadComplete", files);
所以我们只需要绑定到你的上传器,
uploader.bind("UploadComplete", function(files) {
// your code
});
我从未使用过该插件,但此should有效。祝你好运。
如果你必须使用延迟,那么你总是可以使用像这样的伪代码:
var uploader = $('#plupload_container').pluploadQueue();
var def = $.Deferred();
uploader.bind("UploadComplete", function(files) {
def.resolve(files);
});
$('#submitButton').click(function() {
if (uploader.files.length > 0) {
uploader.start();
def.done(function(files) {
def = $.Deferred(); // reset the deferred object.
// rest of your click handler.
});
}
});
答案 1 :(得分:3)
在假想的上传会话中:
var files = ["file1.txt", "file2.txt", "file3.txt"];
这些是我们要上传的文件。让我们组装另一个数组,每个上传都有一个延迟对象:
var uploads = files.map(upload_one);
我们用这个延迟对象数组调用$ .when(),我们还指定每次上传后要做什么,什么时候失败以及什么都完全完成:
$.when(uploads)
.progress(function() {
// report to user, step progress bar, etc
})
.fail(function() {
// display error
})
.done(function() {
// all uploads finished, do stuff
});
这是每个单独上传的工作功能。它返回 deferred 对象,并调用成功或错误函数以响应单个上传:
function upload_one(file) {
var deferred = new $.Deferred();
// start upload
// if finished:
deferred.notify();
deferred.resolve();
// if failed:
deferred.reject();
return deferred;
}
答案 2 :(得分:-1)
是。在ajax api中jquery的新延迟点是允许你的代码等待其他异步代码。
如果您有多个相互依赖的异步调用,则延迟将允许您在完成后执行某些操作。同样的想法适用于此。