如何解决多个动态初始化时只有一个 Dropzone 工作
我正在编写一个 web 应用程序,我需要根据服务器内容初始化多个 dropzones,我目前有一个与此类似的代码:
<script src="/js/dropzone.min.js"></script>
<script>
Dropzone.autoDiscover = false;
window.dropzones = {};
function checkDropzones(container) {
var possibleDropzones = container.querySelectorAll('.needs-to-be-dropzoned');
possibleDropzones.forEach(function (zone) {
if (zone.id.length === 0) {
zone.id = 'dropzone_filled_' + (new Date()).getTime();
window.dropzones[zone.id] = new Dropzone(
'#' + zone.id,{
paramName: 'image',addRemoveLinks: true,}
);
}
})
}
function renderServerContent() {
window.customSections.forEach(function (custom_section) {
var container = document.getElementById(custom_section);
$.ajax({
method: 'GET',url: '/customRenderUrl?section=' + custom_section,headers: {
Accept: 'application/json','Content-Type': 'application/json'
},success: function (response) {
container.innerHTML = container.innerHTML + response.component;
if (response.component_type === 'image_uploader') {
checkDropzones(container);
}
// ... other marginal stuff ...
},dataType: 'json'
})
})
}
// ... other scripts ...
window.customSections = [/* server stuff */];
renderServerContent();
</script>
基本上,我有一些东西要从服务器动态呈现,所以我发送一个请求,要求组件呈现数据,当我得到答复时,我检查插入的内容是否包含带有 .needs-to-be-dropzoned
的元素,如果是这样,我会为它分配一个基于时间的 ID(组件渲染在每个组件之间有延迟,因此 ID 是唯一的)并实例 dropzone。这仅适用于一个 dropzone,但当多个放置在同一页面上时,它不会产生错误,但仅适用于页面上的最后一个元素。
服务器内容是这样的:
<form
class="col-12 container-fluid pb-2 dropzone needs-to-be-dropzoned"
method="POST"
action="/imageUploadUrl"
>
<input type="hidden" name="_token" value="..." >
<div class="dz-default dz-message">
Upload files
</div>
<div class="fallback">
<input name=image" type="file" />
</div>
</form>
如果我启动一个 console.dir(window.dropzones)
,我会得到 2 个对象:
Object { dropzone_filled_1624370363574: {…},dropzone_filled_1624370363803: {…} }
dropzone_filled_1624370363574: Object { element: form#dropzone_filled_1624370363574.col-12.container-fluid.pb-2.dropzone.needs-to-be-dropzoned.dz-clickable,version: "5.9.2",clickableElements: (1) […],… }
dropzone_filled_1624370363803: Object { element: form#dropzone_filled_1624370363803.col-12.container-fluid.pb-2.dropzone.needs-to-be-dropzoned.dz-clickable,… }
我做错了什么或遗漏了什么?
解决方法
我做了各种尝试来解决这个问题,最后,我通过将所有服务器调用包装到承诺中来修复它,等待所有承诺解决,然后才检查 dropzones。代码大概是这样的:
<script src="/js/dropzone.min.js"></script>
<script>
Dropzone.autoDiscover = false;
window.dropzones = {};
window.containersToCheck = [];
function checkDropzones(container) {
var possibleDropzones = container.querySelectorAll('.needs-to-be-dropzoned');
possibleDropzones.forEach(function (zone) {
if (zone.id.length === 0) {
zone.id = 'dropzone_filled_' + (new Date()).getTime();
window.dropzones[zone.id] = new Dropzone(
'#' + zone.id,{
paramName: 'image',addRemoveLinks: true,}
);
}
})
}
function renderServerContent() {
return new Promise(function(resolve,reject) {
window.customSections.forEach(function (custom_section) {
var container = document.getElementById(custom_section);
$.ajax({
method: 'GET',url: '/customRenderUrl?section=' + custom_section,headers: {
Accept: 'application/json','Content-Type': 'application/json'
},success: function (response) {
container.innerHTML = container.innerHTML + response.component;
if (response.component_type === 'image_uploader') {
window.containersToCheck.push(container);
}
resolve();
// ... other marginal stuff ...
},dataType: 'json'
})
})
});
}
// ... other scripts ...
window.customSections = [/* server stuff */];
var promises = [];
promises.push(renderServerContent());
// other renderings
Promise.all(promises).then(function (results) {
window.containersToCheck.forEach(function(container) {
checkDropzones(container);
});
})
</script>
这样,所有 Dropzone 都可以工作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。