我尝试在 XMLHTTPRequest 完成时分派自定义事件,并让侦听器捕获该事件并启动下一个操作。但是,事件侦听器没有按预期触发。我通过将相同的事件侦听器添加到
window
来测试它,它可以工作,但当事件侦听器添加到挂钩中时则不起作用,如下所示。我做错了什么?
Uploaders.Cloudinary_Direct = function(entries, onViewError){
entries.forEach(entry => {
let formData = new FormData()
let {url, fields} = entry.meta
Object.entries(fields).forEach(([key, val]) => formData.append(key, val))
formData.append("file", entry.file)
formData.append("upload_preset", "avatar_upload");
let xhr = new XMLHttpRequest()
onViewError(() => xhr.abort())
xhr.onload = () => {
if (xhr.status === 204) {
entry.progress(100)
}
else{ entry.error()}
}
xhr.onerror = () => entry.error()
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
console.log("public_id")
let event = new CustomEvent("cloudinary_external_upload", {bubbles: true, cancelable: true,
detail: {
public_id: get_public_id(xhr)
}
});
this.dispatchEvent(event); // also tried window.dispatchEvent.. in vain
}
}
xhr.upload.addEventListener("progress", (event) => {
if(event.lengthComputable){
let percent = Math.round((event.loaded / event.total) * 100)
if(percent < 100){ entry.progress(percent) } else {
entry.progress(100) }
}
})
xhr.open("POST", url, true)
xhr.send(formData)
})
}
Hooks.ExternalUpload = {
mounted(){ // <-- This ensures the listener is add only after the component is mounted.
this.el.addEventListener('cloudinary_external_upload', e => {
console.log("cloudinary_upload") // <-- This is never printed.
this.pushEvent("external_upload", {id: this.el.id, public_id: e.originalEvent.detail.public_id});
});
}
}
let liveSocket = new LiveSocket("/live", Socket, {
hooks: Hooks,
uploaders: Uploaders
})
可能有几个问题导致您的事件侦听器未按预期触发: 以下是重构代码来解决这些问题的方法:
Hooks.ExternalUpload = {
mounted() {
const el = this.el; // Capture the correct scope
const cloudinaryUploadHandler = function(e) {
console.log("cloudinary_upload");
this.pushEvent("external_upload", { id: el.id, public_id: e.detail.public_id });
};
this.el.addEventListener('cloudinary_external_upload', cloudinaryUploadHandler.bind(this)); // Bind the correct scope
// Clean up event listener when the hook is destroyed
this.handleEvent("disconnect", () => {
this.el.removeEventListener('cloudinary_external_upload', cloudinaryUploadHandler);
});
}
}