我正在使用jQuery文件上传和KnockoutJS构建资产管理器。麻烦的是,当我上传一组几个文件时,在看似随机的时间我收到了异常
Uncaught Error: cannot call methods on fileupload prior to initialization; attempted to call method 'process'
在集合中某个文件的add
回调中间。
每次将文件添加到上传队列时,我首先执行一个AJAX请求,以便预先注册'服务器上的新资产。之后,我调用jquery.fileupload-process
插件以执行客户端文件验证。简化为:
function add(ev, data) {
// perform an AJAX request through the Knockout view model
viewModel.addAsset().done(function(asset) {
data.asset = asset;
}).done(function() {
data.process(function () {
return $element.fileupload('process', data); // EXCEPTION OCCURS HERE
}).done(function() {
data.submit();
});
});
};
这个问题似乎与时间安排有关。使用相同的20个文件集上传时,有时会在第五个,第七个,第十五个文件上发生错误 - 或者根本不发生错误。
以下是绑定的完整代码:
ko.bindingHandlers.uploader = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var $element = $(element),
options = ko.unwrap(valueAccessor()),
fileUploadConfig,
fileUpload,
doneHandler;
fileUploadConfig = {
dataType: 'json',
type: 'PUT',
url: '/assets', // will be overriden individually after processing
autoUpload: true,
sequentialUploads: true,
dropZone: options.dropzone,
acceptFileTypes: /(\.|\/)(jpe?g|png|mp3|aac|mp4)$/i,
maxFileSize: 250000000
};
fileUploadConfig.add = function add(ev, data) {
if (DEBUG) { console.assert(data.files.length === 1, "expected the add handler to be called with a single file, got " + data.files.length); }
var kind = data.files[0].type.split('/')[0],
file_name = data.files[0].name;
console.log("adding %s", file_name);
viewModel.addAsset(kind).done(function(asset) {
console.log("AJAX call complete, Knockout data model created for file %s", file_name);
data.asset = asset;
data.asset.upload_file_name(file_name);
data.asset.upload_status('waiting');
data.url = asset.resource_path;
}).done(function() {
data.process(function () {
console.log("calling processing plugin for file %s", file_name);
// EXCEPTION OCCURS HERE
return $element.fileupload('process', data);
}).done(function() {
console.log('processing done, submitting %s', file_name);
data.submit();
});
});
};
fileUploadConfig.done = function done(e, data) {
app.services.Asset.refresh(data.asset)
.done(function(asset) {
asset.upload_status('done');
});
};
fileUploadConfig.send = function send(e, data) {
console.log("sending file %s", data.files[0].name);
data.asset.upload_progress(0);
data.asset.upload_status('uploading');
};
fileUploadConfig.progress = function progress(e, data) {
if (data.asset.upload_status() !== 'uploading') {
return;
}
var percentage = parseInt(data.loaded / data.total * 100, 10);
if (percentage >= 100) {
data.asset.upload_status('processing');
data.asset.upload_progress(null);
} else {
data.asset.upload_progress(percentage);
}
};
fileUploadConfig.fail = function fail(e, data) {
console.log("failure file %s", data.files[0].name);
data.asset.upload_status('failed');
app.services.Base._defaultFailureHandler(data.jqXHR);
app.services.Base.failure422Handler(data.jqXHR);
};
console.log("initializing jQ fileUpload");
fileUpload = $element.fileupload(fileUploadConfig);
}
};
控制台调试语句的示例输出如下所示:
对我来说,在已成功处理文件之后,jQuery文件上传应突然未初始化,这对我来说完全没有意义。这是异常时的调用堆栈:
如果我暂停异常,请转到我return $element.fileupload('process', data);
处的框架并检查控制台中的$element.data()
,我会收到
Object {bind: "uploader: {dropzone: $('.upload-manager-overlay')}"}
- jQuery文件上传当然仍然存在。
很抱歉没有提供工作小提琴,但我无法提供此工作所需的上传服务器端点。
如果有任何提示或进一步的调试建议,我将不胜感激。
答案 0 :(得分:0)
原来我做了一些愚蠢的事情:附加了<input type=file>
jQuery文件上传是Knockout呈现的信息面板的一部分。第一个文件成功传输后,此信息面板即被删除。
jQuery文件上传并不奇怪,不能很好地绑定到已经脱离DOM的DOM元素。