按照本教程,我在 Rails 应用程序中使用 Dropzone.js 实现了拖放图像上传:https://web-crunch.com/posts/rails-drag-drop-active-storage-stimulus-dropzone
现在我还想在上传图像之前将其调整为最大宽度。 Dropzone.js 有一个
transformFile
函数用于此目的,但我还没有设法使其工作。我已经尝试过以下方法。
当我创建 dropzone 元素时,我声明了最大宽度 (
resizeWidth
):
function createDropZone(controller) {
return new Dropzone(controller.element, {
url: controller.url,
headers: controller.headers,
maxFiles: controller.maxFiles,
maxFilesize: controller.maxFileSize,
acceptedFiles: controller.acceptedFiles,
addRemoveLinks: controller.addRemoveLinks,
resizeWidth: 200,
autoQueue: false
});
}
然后,我在
transformFile
事件监听器中调用函数 addedfile
:
this.dropZone.on("addedfile", file => {
this.dropZone.options.transformFile(file);
setTimeout(() => {
file.accepted && createDirectUploadController(this, file).start();
}, 500);
});
但是控制台的响应是
Uncaught TypeError: Cannot read property 'resizeWidth' of undefined
有人可以帮助我吗?
遇到的错误是因为在此示例中,
this
函数内的transformFile
未绑定到正确的上下文。要消除错误,您必须将其绑定回 dropzone 控制器,如下所示:
const transformFile = this.dropZone.options.transformFile.bind(this.dropZone)
transformFile(file);
但是
transformFile
方法接受第二个参数,它是转换完成时的回调函数。正确的使用方法如下:
this.dropZone.on('addedfile', async (file) => {
const resizeFunction = async (file) => {
return await new Promise((resolve) => {
// Rely on dropzone built-in resize implementation:
const transformFile = this.dropZone.options.transformFile.bind(this.dropZone)
transformFile(file, (transformedFile) => {
resolve(transformedFile)
})
})
}
const resizedBlob = await resizeFunction(file)
const resizedFile = new File([resizedBlob], file.name, { type: resizedBlob.type })
/// .. rest of the implementation
}
您会注意到,这与 dropzone 的其他功能(例如删除文件)不能很好地集成,对调整大小的调用必须在
new DirectUpload
之前发生,因此您必须进行修改以传递 dropzone 实例或 resizeFunction
到 createDirectUploadController
一直到那个点。
这就是我的应用程序中最终调用站点的样子:
const resizedBlob = await resizeFunction(file)
const resizedFile = new File([resizedBlob], file.name, { type: resizedBlob.type })
return new DirectUpload(resizedFile, url, controller)