加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – Rails ActiveStorage:DirectUpload回调

发布时间:2020-12-17 03:10:53 所属栏目:百科 来源:网络整理
导读:我在使用ActiveStorage的DirectUpload对象时遇到了一些麻烦.我正在跟踪RailsGuides中的示例,但我必须遗漏一些东西.这是我的问题的快速布局: 我想要完成的任务. 我已经尝试过做什么. 我目前的问题是什么. 1.我想要完成的任务 使用ActiveStroage,我试图允许用
我在使用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)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读