从plupload队列中删除文件?

时间:2012-11-16 20:00:50

标签: javascript ajax file-upload plupload

我正在尝试限制可以通过plupload上传的文件扩展名。

因为过滤器无法与HTML5运行时一起使用,我无法使用它们。因此我将下面的代码绑定到FilesAdded事件

var extensionArray = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'];
uploader.bind('FilesAdded', function (up, files) {
    var invalid = 0;
    for (var i in files) {
        var extension = files[i].name
                                .substr((files[i].name.lastIndexOf('.') + 1))
                                .toLowerCase();

        if (extension == '' || -1 === $.inArray(extension, extensionArray)) {
            uploader.splice(i, 1); //also tried uploader.removeFile(files[i])
            invalid++;
            continue;
        }
        //dom manipulation to add file occurs here
    }
});

但是,虽然这会停止对任何无效文件进行dom操作,但它似乎并没有实际从队列中删除项目,因为当我启动上传时,它们都被发送过来了!

HTML5和Flash Runtime都会发生这种情况。我还没有测试过其他人。

绑定到FilesRemoved事件,它永远不会被触发!但是在console.log('Invalid files detected');之前插入uploader.splice(...会将其输出到控制台,以便调用该行。

2 个答案:

答案 0 :(得分:2)

简短版本:您需要在调用filesAdded函数后绑定到init()事件

我调试的第一步是抓住the uncompressed version off github 2012年11月18日。有一次,我可以追踪这个问题。

所以主要的问题似乎是对removeFile()的调用永远不会被调用,但为什么呢?

removeFile()定义为:

removeFile: function (file) {
    var i;

    for (i = files.length - 1; i >= 0; i--) {
        if (files[i].id === file.id) {
            return this.splice(i, 1)[0];
        }
    }
}

好的,很简单,这会循环遍历文件数组,如果有一个具有匹配ID的文件,那么我们调用splice函数。

那么,拼接是什么样的?

splice()定义为:

splice:function (start, length) {
    var removed;

    // Splice and trigger events
    removed = files.splice(start === undef ? 0 : start, length === undef ? files.length : length);

    this.trigger("FilesRemoved", removed);
    this.trigger("QueueChanged");

    return removed;
}

是的,那就是应该触发FilesRemoved事件的地方,为什么不是呢?

如上所述,返回removeFile()函数,如果找到匹配的ID,则只会调用splice

因此,下一步是找出removeFile函数是否被调用。

插入console.log('removeFile called', files);作为第一行,为我们提供了输出:removeFile called []

嗯,一个空阵列!

好的,看起来我们绑定到FilesAdded事件正在停止它的通常行为,没问题。我们只需将uploader.files.push(file)添加到我们的FilesAdded绑定中。并且看哪。当我们点击开始时,只发送正确的文件。

它正在运作......但并不完全 我在那里有几个额外的绑定,仅用于调试目的,其中一个在QueueChanged上。这会在每次发生更改时记录队列中的文件数量。

我注意到的是队列中的文件数实际上并没有反映出从队列中删除了文件。

所以,快速console.log(uploader.files.length)并确认此处还有其他内容。

下一步是查看添加文件的默认操作。

看着我注意到开发人员决定绑定到事件,在init函数中执行此操作。从我的角度来看这个奇怪的选择。但这是他们的选择。

所以,看看他们的绑定,他们也有files.push(file)意味着我们得到了数组中正确文件的所有文件+重复。

注意到绑定发生在init(),函数中,我从绑定中删除了uploader.files.push(file),将init()调用移到我的FilesAdded绑定之前。现在一切正常。

答案 1 :(得分:-1)

uploader=newplupload.Uploader({
//-----
});

uploader.bind('FilesAdded',function(up,files)
{
//----
up.refresh();//RepositionFlash/Silverlight
});

uploader.bind('QueueChanged',function(up,files){

//#doc-filelist is the id of dive, which shows the Queue
$('#doc-filelist').html('');

$.each(uploader.files,function(i,file){
$('#doc-filelist').append(
'<div id="'+file.id+'">'+
file.name+'('+plupload.formatSize(file.size)+')<b></b>'+
'<spanclass="remove_file"data-file="'+i+'">X</span>'+
'</div>');
});

if(uploader.files.length==0){
 // #uploadfiles button for start upload
$('#uploadfiles').addClass('disabled');
}

});

 uploader.bind('UploadComplete', function (up, file) {
    up.splice();
    up.refresh();

}); 


$('.relevant-document').on('click','.remove_file',function(e){

uploader.splice($(this).attr('data-file'),1);

uploader.refresh();
});