我该如何解决这个 "Dropzone already attached" 错误?

How can I fix this "Dropzone already attached" error?

我有这个样本:

link

我设法创建了这个表单,但不幸的是它不起作用,因为我收到错误。

Dropzone already attached.

代码 HTML:

<div class="dropzone dz-clickable" id="myDrop">
  <div class="dz-default dz-message" data-dz-message="">
    <span>Drop files here to upload</span>
  </div>
</div>

代码 JS:

Dropzone.autoDiscover = false;
var myDropzone = new Dropzone("div#myDrop", { url: "/file/post"});

// If you use jQuery, you can use the jQuery plugin Dropzone ships with:
$("div#myDrop").dropzone({ url: "/file/post" });

我设置了 Dropzone.autoDiscover = false; 但遗憾的是仍然无法正常工作。

你能告诉我是什么导致了这个问题吗?

您应该使用

var myDropzone = new Dropzone("div#myDrop", { url: "/file/post"});

$("div#myDrop").dropzone({ url: "/file/post" });

两者都不是。基本上你正在做的是两次调用同一件事。

当元素已经有 class dropzone.

时,也会发生此错误

但是,如果将其删除,则出于某种原因默认样式将不会在启动 Dropzone 后应用。我唯一的解决方法是为该元素创建自定义样式。

全局定义以下代码将有所帮助:

Dropzone.autoDiscover = false;

这是我的 hackish 解决方法。它主要检查 dropzone 是否作为 DOM 加载,如果没有,那么它将创建一个。

    function dropzoneExists(selector) {
        var elements = $(selector).find('.dz-default');
        return elements.length > 0;
    }

    var exists = dropzoneExists('div#photo_dropzone');
    if(exists) return;

    $('div#photo_dropzone').dropzone({
       ...
       ...
    });

UPDATE: 建议搞清楚dropzone为什么会启动两次。解决这个问题是正确的方法,这个答案只是一个 技术上有问题的 解决方法。

在网上搜索并尝试了几种解决方案后,我在这里找到了解决此问题的最佳解决方案之一。

HTML

<div id="some-dropzone" class="dropzone"></div>

JavaScript

Dropzone.options.someDropzone = {
  url: "/file/post"
};

有时是因为您有两个具有相同 ID dropzone 的元素 html。

<div id="dropzone" class="dropzone"></div>

<div id="dropzone" class="dropzone"></div>

我通过编辑 dropzone.js 解决了这个问题。只需转到 dropzone.js 并替换

if (this.element.dropzone) {
    throw new Error("Dropzone already attached.");
  }

if (this.element.dropzone) {
    return this.element.dropzone;
 }

此解决方案最初由 Haskaalo, posted on the github issues

找到

您可以将您的 ID "myDrop" 与每个 Dropzone 实例的唯一值连接起来。

示例:

 html: <span className="custom-file-input" id={"my-dropzone" + this.dropzoneId}></span>

 in func: 
 this.myDropzone = new Dropzone("span#my-dropzone" + this.dropzoneId, options);
<script>
  Dropzone.autoDiscover = false;
  $(document).ready(function() {
    var myDrop= new Dropzone("#myDrop", {
      url: '/admin/media'
    });
  });
</script>

而不是

<script>
  $(document).ready(function() {
    Dropzone.autoDiscover = false;
    var myDrop= new Dropzone("#myDrop", {
      url: '/admin/media'
    });
  });
</script>

使用 Angular 时,此解决方案对我不起作用:

Dropzone.autoDiscover = false;

我可以让它与 Angular 一起工作而无需编辑 dropzone.js 文件的唯一方法是:

@ViewChild('containerElement') containerElement: ElementRef;

...    

/* Make sure all Dropzone instances are destroyed */
if (Dropzone.instances.length > 0) {
    Dropzone.instances.forEach((e: any) => {
        e.off();
        e.destroy();
    });
}

/* Remove existing dropzone element from the DOM */
const element: any = document.getElementById('my-dropzone');
element.remove();

/* Create new dropzone DOM element */
const html =
` <div id="my-dropzone" class="dropzone">` +
    `<div class="dz-message">` +
    `<i class="fad fa-cloud-upload-alt dz-message-icon"></i>` +
    `<p>Drop files, or click to browse</p>` +
    `</div>` +
`</div>`;
this.containerElement.nativeElement.insertAdjacentHTML('beforeend', html);

像这样在 $(document).ready 之前添加 Dropzone.autoDiscover = false

Dropzone.autoDiscover = false;
$(document).ready(function () {

});

转到 dropzone.js 并替换 if(n.element.dropzone) throw new Error("Dropzone already attached."; with if(n.element.dropzone) return this.element.dropzone;