ruby-on-rails – Rails ActiveStorage:DirectUpload回调
我在使用ActiveStorage的DirectUpload对象时遇到了一些麻烦.我正在跟踪RailsGuides中的示例,但我必须遗漏一些东西.这是我的问题的快速布局:
>我想要完成的任务. 1.我想要完成的任务 使用ActiveStroage,我试图允许用户在一个简单的表单上选择多个文件,并在选择文件后自动启动直接上传. 这是与最终用户交互的表单: _media_upload_form.html.erb <%= form_with url: elements_upload_path,local: true,id: "upload-elements" do %> <span class="btn btn-primary btn-file"> <%= form.file_field :images,multiple: true,direct_upload: true %> Select File(s) </span> <% end %> 2.我已经尝试过做什么 要在用户选择文件后完成自动文件上传,我必须直接与DirectUpload对象进行交互.这个提示可以在ActiveStroage RailsGuides上找到.我可以使用以下JS代码来解决这个问题: direct_uploads.js import { DirectUpload } from "activestorage" const input = document.querySelector('input[type=file]') const onDrop = (event) => { event.preventDefault() const files = event.dataTransfer.files; Array.from(files).forEach(file => uploadFile(file)) } input.addEventListener('change',(event) => { Array.from(input.files).forEach(file => uploadFile(file)) input.value = null }) const uploadFile = (file) { const url = input.dataset.directUploadUrl const upload = new DirectUpload(file,url) upload.create((error,blob) => { if (error) { // Handle the error } else { const hiddenField = document.createElement('input') hiddenField.setAttribute("type","hidden"); hiddenField.setAttribute("value",blob.signed_id); hiddenField.name = input.name document.querySelector('form').appendChild(hiddenField) } }) } 所以,我完成了一个目标.我们在选择文件后立即上传文件.现在,我的下一个目标是访问事件,因此我知道上传完成,进度等等.了解上传完成的时间尤为重要,这样我就可以提交表单并创建对象并将其附加到上传的文件中.所以,使用这样的东西: addEventListener("direct-upload:progress",event => { // ... }) 不起作用,因为我直接访问DirectUpload对象.至少,这是我迄今为止的经历.有点疑惑为什么,我注意到ActiveStroage RailsGuides中的一个细节(我最初忽略了),它说你可以通过创建自己的DirectUpload上传类来绑定处理程序.因此,使用指南中提供的示例,我创建了以下内容: my_uploader.js import { DirectUpload } from "activestorage" class MyUploader { constructor(file,url) { this.upload = new DirectUpload(this.file,this.url,this) } upload(file) { this.upload.create((error,blob) => { if (error) { // Handle the error } else { const hiddenField = document.createElement('input') hiddenField.setAttribute("type","hidden"); hiddenField.setAttribute("value",blob.signed_id); hiddenField.name = input.name document.querySelector('form').appendChild(hiddenField) } }) } directUploadWillStoreFileWithXHR(request) { request.upload.addEventListener("progress",event => this.directUploadDidProgress(event)) } directUploadDidProgress(event) { console.log("Upload has some progress ....") } } // ... all ES6 export calls ... direct_uploads.js import { DirectUpload } from "activestorage" import { MyUploader } from "my_uploader" const input = document.querySelector('input[type=file]') const onDrop = (event) => { event.preventDefault() const files = event.dataTransfer.files; Array.from(files).forEach(file => uploadFile(file)) } input.addEventListener('change',(event) => { Array.from(input.files).forEach(file => uploadFile(file)) input.value = null }) const uploadFile = (file) { const url = input.dataset.directUploadUrl const upload = new MyUploader(file,url) } 3.我目前的问题是什么 我认为我的问题是我错过了一些东西,也许是一个步骤.正在调用MyUploader构造函数,但不再上载文件.只调用构造函数,就是这样.不再调用实际的上载进程.我迷失了如何使自定义MyUploader继续上传过程,就像DirectUpload对象一样. 任何人都能提供的任何方向都将不胜感激. 谢谢! 解决方法
离开我的项目一段时间后,用新鲜的眼睛回来,我看到了答案.
DirectUpload可以有三个参数,第三个是MyUploader对象. 所以答案是这样的: const my_uploader = new MyUploader(file,url) const upload = new DirectUpload(file,url,my_uploader) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |