У меня возникли проблемы с работой напрямую с объектом 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.
Будем весьма благодарны за любые указания, которые может предоставить любой пользователь.
Спасибо!